2014年2月18日火曜日

【Objective-C】乱数と配列を使用した一意な数値の求め方

◆サンプルプログラムの説明
arc4randm() 使って1から43までのランダム値を求める。
求めた数値は配列に格納するが、containsObjectで配列存在チェックをして、存在しない値の場合のみ配列し、6回格納したらループを抜けるという処理。
最後にテキストフィールドに代入して画面に表示します。














2014年2月16日日曜日

【Objective-C】FMDBを利用してDB(SQlite)に接続して操作する方法

SQLiteのWrapper ライブラリであるFMDBを利用して SQLiteを操作するサンプルプログラムを作成しました。

◆事前準備

1.FMDBの取得
 こちらのサイトからソースコードをDownLoadします。

2.プロジェクトに追加
 FMDBのソースコードをプロジェクトに追加し、FMDBを利用できるようにします。
 サブフォルダを作成して、まとめて配置するとよいでしょう。


















 #fmdb.mは追加不要です。


3.FMDBを利用したデータベースプログラミング
 プログラム内でDBを作成してテーブルを作成する方法です。
 作成したDBは

 1.インクルードをする。
  #import "FMDatabase.h"

 2.作成されたDBが保存される場所
  /Users/username/Library/Application Support/iPhone
   Simulator/XXX/Applications/XXX/Documents/
  ※OsLion以降ではLibralyが隠しフォルダになっているので
   ターミナルでコマンドを入力して表示されるようにする必要があります。
   コマンド:chflags nohidden ~/Library/

 3.サンプルソース
  getPathメソッドでLibralyパスを取得しておく。
  あとはDBの作成・参照、テーブル作成、登録、抽出のメソッドのサンプルとなっています。
  DB_NAMEは定数を宣言しておいてください。

// Liblary pathの取得
- (void)getPath{
    NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory
                                                         , NSUserDomainMask, YES
                                                         );
    _dir = [paths objectAtIndex:0];
}


// DBの作成・参照
- (void)createDB{
    FMDatabase* db = [FMDatabase databaseWithPath:[
                                                   _dir stringByAppendingPathComponent:
                                                   DB_NAME
                                                  ]
                     ];
    //実行
    [db open];
    [db close];
}


// テーブル作成
- (void)createTable{
    FMDatabase* db = [
                      FMDatabase databaseWithPath:[
                                                   _dir stringByAppendingPathComponent:
                                                   DB_NAME
                                                   ]
                      ];

    NSString* sql = @"CREATE TABLE IF NOT EXISTS testTB (id TEXT,name TEXT);";
    
    [db open];
    [db executeUpdate:sql];
    [db close];
}

// テーブル登録
- (void)insTable{
    FMDatabase* db = [
                      FMDatabase databaseWithPath:[
                                                   _dir stringByAppendingPathComponent:
                                                   DB_NAME
                                                   ]
                      ];
    
    NSString* sql = @"INSERT INTO testTB (id ,name) VALUES (?,?)";
    
    [db open];
    [db executeUpdate:sql, @"aaa2" , @"bbb2"];
    [db close];
}

【Objective-C】簡単なクラスサンプルとプロパティ使い方(Private,Public)

calcクラスはプロパティに設定された2つの値に対して、足し算、引き算のメソッドを実装する簡単なサンプルです。ここでのポイントは、プロパティを定義するとインスタンス変数が自動で生成されているところです。

このサンプルプログラムのプロパティ(valCal1)に対して、インスタンス変数(_valCal1)が自動で生成されています。また、プロパティ(valCal2)に対しても同様にインスタンス変数が自動で生成されています。このサンプルプログラムでは足し算、引き算の各メソッドに対して、インスタンス変数を利用して計算した結果とプロパティを利用して計算した結果の値を確認しています。

結論としてインスタンス変数もプロパティも同様の値が設定されており、結果としてはどちらの値を利用してもよいということになります。

Ojbect-CではメソッドにPrivate,Publicの概念がないらしいのですが、ヘッダーファイルの@interfaceにメソッド定義すると外部参照できる仕組みなので、実装ファイルの@interface部分にのみメソッド定義すればPrivateメソッドと同じように扱えます。

以降はサンプルプログラムです。

◆calcクラスのヘッダーファイル
メソッドやプロパティを定義します。

@interface calc : NSObject
//メソッド定義
- (id)calc_Init;
- (int)calc_Tasu;
- (int)calc_TasuP;
- (int)calc_Hiki;
- (int)calc_HikiP;
//プロパティ
@property(nonatomic) int valCal1;
@property(nonatomic) int valCal2;
@end

◆calcクラスの実装ファイル
#import "calc.h"

@interface calc()
//-(int) calc_hiki2; Privateにする場合はヘッダーファイルに定義しない
@end

@implementation calc

-(id) calc_Init
{
    return self;
}

// 足し算(インスタンス変数)
-(int)calc_Tasu
{
    // 戻り値返却
    return _valCal1 + _valCal2;
}

// 足し算(プロパティ)
-(int)calc_TasuP
{
    // 戻り値返却
    return self.valCal1 + self.valCal2;
}

// 引き算(インスタンス変数)
-(int)calc_Hiki
{
    // 戻り値返却
    return _valCal1 - _valCal2;
}

// 引き算(プロパティ)
-(int)calc_HikiP
{
    // 戻り値返却
    return self.valCal1 - self.valCal2;
}

@end

◆呼び出し側の処理
・・・
{
    //インスタンス生成
    calc *myCalc = [[calc alloc]calc_Init];
 
    //足し算 (インスタンス変数
    myCalc.valCal1 = 1;    myCalc.valCal2 = 2;
    int retTasu = [myCalc calc_Tasu];

    //足し算 (プロパティ)
    myCalc.valCal1 = 2;    myCalc.valCal2 = 2;
    int retTasuP = [myCalc calc_TasuP];

    //引き算 (インスタンス変数)
    myCalc.valCal1 = 10;    myCalc.valCal2 = 5;
    int retHiki = [myCalc calc_Hiki];

    //引き算 (プロパティ)
    myCalc.valCal1 = 10;    myCalc.valCal2 = 8;
    int retHikiP = [myCalc calc_HikiP];
 
    //結果
    NSLog(@"足し算(インスタンス変数):%d" ,retTasu);
    NSLog(@"足し算(プロパティ):%d" ,retTasuP);
    NSLog(@"引き算(インスタンス変数):%d" ,retHiki);
    NSLog(@"引き算(プロパティ):%d" ,retHikiP);
}

◆NSLogの結果
 足し算(インスタンス変数):3
 足し算(プロパティ):4
 引き算(インスタンス変数):5
 引き算(プロパティ):2

2014年2月15日土曜日

【SQLSERVER】SQLで数値の連番を取得する方法

テーブルを増やしていけばいくらでも連番の生成が可能。
テーブルの結合条件を指定せずに各テーブルの結果を積算し、重み付けして集計する。

◆1から999までの数値
select X.col + XX.col * 10 + XXX.col * 100
   from (
             select 1 union select 2 ・・・
            ) X
           ,(
             select 1 union select 2 ・・・
            ) XX
          , (
             select 1 union select 2 ・・・
            ) XXX
order by X.col + XX.col * 10 + XXX.col * 100


【SQLSERVER】Or指定をUnion化してインデックスを有効活用する方法

col1、col2にインデックスが存在する場合に有効。

◆改善前
select *
   from XXX
  where col1 = AAA
       or col2 = BBB

◆改善後
select *
   from (
             select * from XXX where col1 = AAA Union
             select * from XXX where col2 = BBB
            ) XXX

【SQLSERVER】集計関数 min maxを利用した重複チェックの方法

特定項目に対して重複データが存在するかのチェックなど。

◆データ
col1  col2
A      りんご
A   りんご
B       りんご
C      りんご
C       みかん

select col1 , min(col2) ,max(col2)
 group by col1
 having min(col2) <> max(col2)

◆結果
col1   min    max
-------------------------------
C       みかん りんご

【SQLSERVER】複数列を1行にして集計する方法

case文を利用して集計したい項目名に合致するデータのみ集計対象とし、合致しない場合は0を定義して集計対象外とする。

◆データ
 col1  col2
 ---------------
 東京都 3
 千葉        1
 千葉        3
 千葉        2
 神奈川    5


select  sum(case when col1 = '東京' then col2 else 0 end) 東京集計
          ,sum(case when col1 = '千葉' then col2 else 0 end) 千葉集計
          ,sum(case when col1 = '神奈川' then col2 else 0 end) 神奈川集計
   from xxx

◆結果
 東京集計 千葉集計 神奈川集計
 -------------------------------
    3               6               5


【Objective-C】ラベルのクリックイベントを取得する方法

クリックされたラベルのタグで処理を分岐したりすることができる。(touch.view.tag)
イベントを取得するには、ラベル生成時に下記を設定する必要がある。
label.userInteractionEnabled = true;

// クリックイベント取得
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //タッチされたオブジェクトを取得
    UITouch *touch = [[event allTouches] anyObject];

    //タグを取得
    label_ans.text = [NSString stringWithFormat:@"%d",touch.view.tag];
}

【Objective-C】ラベルを動的に複数作成する方法

タグに識別数値を設定しているので何がクリックされた判定はできる。

// ヘッダーファイル
{
@private
    UILabel* label;
}

// ソースファイル
    int x = 20 ,y = 20;
    for (int i=1 ; i<=5; i++)
    {
        label= [[UILabel alloc] init];
        label.userInteractionEnabled = true;
        label.frame = CGRectMake(x , y, 120, 20);
        label.text = [NSString stringWithFormat:@"氏名:%d", i];
        label.tag = i;
        [self.view addSubview:label];
        y += 30;
    }

◆実行キャプチャ



【Objective-C】ボタンにイベントを設定する方法



    UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    btn.frame = CGRectMake(x, y+30, 60, 70);
    [btn setTitle:@"ボタン" forState:UIControlStateNormal];
    [self.view addSubview:btn];

    // ボタンイベント時の呼び出しメソッド設定
    [btn addTarget:self action:@selector(btnClick:)forControlEvents:UIControlEventTouchDown];
 

-(void)btnClick:(id)sender{
    // 処理  
    NSLog(@"aaa");
}

【Objective-C】動的にボタンを生成する方法(UIButtonクラス)

名称はメソッドで設定する。

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    btn.frame = CGRectMake(x, y+30, 60, 70);
    [btn setTitle:@"ボタン" forState:UIControlStateNormal];
    [self.view addSubview:btn];


【Object-C】メソッドの定義と実行について

◆引数なし、戻り値なしの場合
// 呼び出し元
[self voidTest];

//メソッド定義
-(void)voidTest{
//処理
    NSLog(@"デバッグ:");
}

◆引数なし、戻り値あり(int)の場合
//呼び出し元
int test = [self Test];
self.label2.text = [NSString stringWithFormat:@"%d", test];

-(int)Test{
//処理
    int test ;
    test = 10;
    return test;
}

◆引数なし、戻り値あり(NSString)の場合
//呼び出し元
NSString *test = [self Test];
self.label2.text = test;

//メソッド定義
-(NSString*)Test{
//処理
    NSString *test ;
    test = @"TEST";
    return test;
}

◆引数ありの場合
//呼び出し元
NSString *test = [self Test:@"戻り値" :5];

//メソッド定義
-(NSString*)Test:(NSString *)aaa :(int)bbb{
//処理
    return aaa;
}

【Object-C】動的にテキストフィールドを生成する方法(UITextFieldクラス)

UITextFieldクラスを使用して動的に生成する。色等の指定は別途プロパティ設定すればよい。

    UITextField *text1 = [[UITextField alloc] init];
    text1.frame = CGRectMake(40 ,170 ,150 ,30);
    text1.borderStyle = UITextBorderStyleRoundedRect;
    text1.text = @"ここはテキストエリアです。";

    [self.view addSubview:text1];

【Object-C】動的にラベルを生成する方法(UILabelクラス)

UILabelクラスを使用して動的に生成する。色等の指定は別途プロパティ設定すればよい。

    ◆サンプル
    UILabel *label1 = [[UILabel alloc] init];
    label1.frame = CGRectMake(40, 140, 120, 70); //位置x, 位置y, ,
    label1.text = @"氏名:";

    [self.view addSubview:label1];

【SQLSERVER】重複を取り除いた件数を取得したい

◆データ
col1 col2
--------------
東京 A
東京 B
埼玉 A
千葉 A
千葉 A
茨城 A

◆サンプル
select col1 ,count(distinct col1)  ,count(col1)
  from XXX
group by col1

◆結果
col1 --
---------------
東京 1 2
埼玉 1 1
千葉 1 2
茨城 1 1

集計関数の集計対象に対してDistinctを指定して重複を取り除く事ができる。

【SQLSERVER】関連性のない項目同士を同一行で抽出したい

関連性のない項目同士を同一行で抽出したい場合等。
Row_Numuberを使用して表示したい順に連番を設定し、連番で結合する。連番はPKとなる。

◆データXXX
 col1
 ------------
 A
 B
◆データXXX2
col2
------------



◆サンプル
select XXX.col_key ,xxx.col1 ,xxx2.col1
   from (
             select row_number () over (order by col1) as col_key ,col1 from XXX
            ) XXX
inner join
            (
             select row_number () over (order by col1) as col_key ,col1 from XXX2
            ) XXX2
      on XXX.col_key = XXX2.col_key

◆結果
col_key col1 col2
---------------------
1  A あ
2  B い

# いずれか一方がないばあいも取得したい場合は結合条件をfull joinを指定する。

【SQLSERVER】取得データの特定項目毎に連番を設定する方法

下記例ではcol1毎に連番を1から設定している。(partition句を使用して連番をクリア)

◆データ例
 col1  col2
    -----------------
    東京 A
 東京 B
 東京 C
    埼玉 A
 埼玉 B
 埼玉 C


◆サンプルSQL
select  col1 ,col2 ,row_numer() over(partition by col1 order by col2)
   from XXX

◆結果
 col1  col2 row_number
    -----------------
    東京 A    1
 東京 B    2
 東京 C    3
    埼玉 A    1
 埼玉 B    2
 埼玉 C    3

【SQLSERVER】取得データに連番を設定する方法

selectで取得できることもできますが、条件に設定にも指定できるので、5番目以上のみ取得するなどの使い方ができる。

◆データ例
 col1
    ---------------
    a
    b
    c

◆サンプルsql(colの昇順に1から連番を設定)
select row_number () over (order by col1) as  ,col1
   from XXX

     row_numuber  col1
    ------------------------
    1      a
    2      b
    3      c


◆サンプルsql(colの降順に1から連番を設定)
select row_number () over (order by col1 desc) ,col1
   from XXX


     row_numuber  col1
    ------------------------
    3      a
    2      b
    1      c



【SQLSERVER】テーブル同士に存在しないデータの確認方法

例えばテーブルAにあるがテーブルBに存在しないデータの確認方法。

select *
  from XXX_A
 where not exists (
                             select 1 
                                from XXX_B
                              where 結合条件
                            )


【SQLSERVER】テーブルのコピーを簡単に作成する方法

更新等に一時的にテーブルをバックアップしたい場合に利用する。

◆バックアップ
select * into XXX_20130215 from XXX

◆内容確認
select * from XXX
select * from XXX_20130215

XXX_20130215 という名称のテーブルが作成されてバックアップされている。一時的に保存しておく場合に非常に便利です。

【SQLSERVER】Viewでのソート指定の注意点

SQLSERVER2000ではViewの定義内のソートは有効だったが、以降のVersionでは使えなくなっているので注意。

◆View定義
select * from XXX Order by col1,co2l

◆View使用時
Select * from vw_XXX Order by col1,col2

上記のようにView参照時に並べ替える必要がある。


【SQLSERVER】テーブルから出力したデータに任意の見出しをつけたい

サンプル
select xxx2.col2 ,xxx2.col2
   from (
              -- ヘッダー部
              select 1 as sortKey , "項目A" as col1 ,"項目B" as col2
              union
              -- データ部
              Select 2 , col1 , col2
                 from xxx
            ) xxx2
order by xxx.sortKey

◆結果イメージ
項目A 項目B
AAA    BBB
CCC     DDD


◆説明
Unionのヘッダー部を見出しの固定文字とし、データ部をテーブルからファイルに出力したい項目をとする。ソートの優先順位をヘッダー部 → 明細部となるように固定数値で指定して外側でOrder byする。

【SQLSERVER】テーブルのPKを表示する方法

sp_pkeys テーブル名
テーブルのpkが表示できる。


【SQLSERVER】テーブルの項目を表示する方法

sp_columns テーブル名
テーブルの名称や型が表示できるので便利。

【SQLSERVER】 In句をExists句に置き換える

一般的にExists句のが高速、そのうえカスタマイズ性が高いのでおすすめ。
下記は簡単例です。1テーブルなのであまり意味はないですが。

◆In句
select *
   from xxx
 where col in ('a' ,'b')

◆Exists句
select *
   from xxx
 where Exists (
                        select 1
                           from xxx
                         where col in ('a' ,'b')
                       )

【SQLSERVER】OR条件に対するインデックスの有効活用

Col1にインデックスを設定されているが、Or指定のため活用されない場合は、チューニング後のようにUnion句で条件を指定すると有効活用されて検索結果が高速化される。

◆チューニング前
select *
   from xxx
 where col1 in ('a' ,'b')

◆チューニング後
select *
   from (
             select * from xxx where col1 = 'a' union
             select * from xxx where col2 = 'b'
            )


【Object-C】ハッシュSHA-256のサンプルコード







◆宣言

#include <CommonCrypto/CommonDigest.h>


◇メソッド
- (NSString *)hashed_string:(NSString *)input
{
    const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:input.length];
    uint8_t digest[64];
    
    // This is an iOS5-specific method.
    // It takes in the data, how much data, and then output format, which in this case is an int array.
    CC_SHA256(data.bytes, data.length, digest);
    
    NSMutableString* output = [NSMutableString stringWithCapacity:64];
    
    // Parse through the CC_SHA256 results (stored inside of digest[]).
    for(int i = 0; i < 32; i++) {
        [output appendFormat:@"%02x", digest[i]];
    }
    
    return output;
}

@end