iPhoneでSQLite3を使う3(データの選択)

SQLite3の3回目、基本的なデータ操作について書きます。
1回目で書いた通り、データの操作はSQLで行います。SQLDML文(データ操作言語)には、4つの種類があります。

  • SELECT(選択)
  • INSERT(追加)
  • UPDATE(更新)
  • DELETE(削除)

名は体を表す。見たまんまです。
それでは、ひとつづつサンプルコードを作成していきます。今回は選択についてです。


SELECT文の例
こんな形のテーブルを作成しましたよね。これがテーブルで、構造体の配列みたいなものだという話をしました。
構造体のひとつの変数、IDとかnameのことをDBでは列(カラム)といいます。配列のひとつを行(ロー)といいます。

CREATE TABLE userinfo (
	'ID' integer,
	'name' text,
	'screen_name' text,
	'profile_image_url' text,
	'followers_count' integer,
	'friends_count' integer,
	'text' text
);

SELECT文では、どのテーブルから、どの列のデータを取得したいかを記述します。また、取得するときにこんなデータだけ欲しいという、条件をつけることもできます。

SELECT 列,列… FROM TABLE名 WHERE 条件

例えば、userinfoテーブルから、screen_nameとtextを取得したいのであれば

SELECT screen_name,text FROM userinfo

となります。また、すべての列を取得したいのであれば"*"を指定することができます。

SELECT * FROM userinfo



SQLは、ほどほどにしてObjective-Cで、userinfoテーブルからすべてのデータを取得するには、下記のようになります。

-(NSMutableArray*)userInfoSelect {
	Userinfo* userInfo;
	NSMutableArray *userInfos = [[NSMutableArray alloc] init];

	// ※1 発行するSQL
	NSString* selectSQL = [NSString stringWithFormat:@"select * from userinfo"];

	// ※2 SQLのコンパイル
	sqlite3_stmt *statement = nil;
	if(sqlite3_prepare_v2(db_, [selectSQL UTF8String], -1, &statement, NULL) == SQLITE_OK) {
		int wasSucceeded = 0;

		// 次の行が存在する時、戻り値はSQLITE_ROWを返却する。ないとき、SQLITE_DONEを返却する。
		do
		{
			// ※3 SQLの実行
			wasSucceeded = sqlite3_step(statement);
			if (wasSucceeded == SQLITE_ROW)
			{
				userInfo = [userInfo ID:[self getString:statement column:0]
						   Name:[self getString:statement column:1]
					     ScreenName:[self getString:statement column:2]
				        ProfileImageUrl:[self getString:statement column:3]
				         FollowersCount:[self getNumber:statement column:4]
				           FriendsCount:[self getNumber:statement column:5]
					           Text:[self getString:statement column:6]];
				[userInfos addObject:userInfo];
				[userInfo release];
			} else if(wasSucceeded == SQLITE_DONE) {
				//読み切り
			} else {
				//PREPARE済みSTATEMENTの廃棄
				sqlite3_finalize(statement);
				return nil;
			}
		} while (wasSucceeded == SQLITE_ROW);
	} else {
		return nil;
	}
	// ※5 PREPARE済みSTATEMENTの廃棄
	sqlite3_finalize(statement);

	return userInfos;
}

// ※4 値の取出し
-(NSNumber*)getNumber:(sqlite3_stmt*)statement column:(int)col {
	return [NSNumber numberWithInt:(int)sqlite3_column_int(statement, col)];
}

-(NSString*)getString:(sqlite3_stmt*)statement column:(int)col {
	char *work = (char *)sqlite3_column_text(statement, col);
	if (work == NULL) {
		return nil;
	} else {
		return [NSString stringWithUTF8String:work];
	}
}

※1 selectSQLが発行するSQLになります。SQLはDBで実行する際にコンパイルが必要です。
※2 コンパイルするためのメソッドがsqlite3_prepare_v2です。これが正常に完了すればSQLの実行が可能となります。
※3 SQLのSELECT文の実行は、sqlite3_stepを使います。これを実行すると、配列の1行目が返ってくるイメージです。
※4 値の取出しは、sqlite3_column_intやらsqlite3_column_textを使います。
※5 コンパイルしたSQLの廃棄。お約束です。
sqlite3_stepは、発行するたびに1行目、2行目と次々と行を読み取ってくれます。そしてもう読む行が無くなったら、SQLITE_DONEを返してくれます。
SQLITE_DONEが返されるまで、ぐるぐる読み取る処理を続けます。