忍者ブログ

[PR]

2024年11月21日
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

SQL文への変数組み込みと検索結果取り出しの関数

2008年11月22日
データベースで各列に使うデータ型は主にint、real、charですが、それらをプログラム側とやり取りする時は以下のような感じになります。それぞれプログラム内の変数は
int aInteger;
double aDouble;
NSString *aString;
という場合です。

SQL文の?に埋め込む場合
sqlite3_bind_int(st, 1, aInteger);
sqlite3_bind_double(st, 2, aDouble);
sqlite3_bind_text(st, 3, [aString UTF8String], -1, SQLITE_TRANSIENT);

データを取り出す場合
aInteger = sqlite3_column_int(st, 0);
aDouble = sqlite3_column_double(st, 1);
aString = (char *)sqlite3_column_text(st, 2);
PR

SQL文に変数を組み込んで利用する方法

2008年11月22日
以前にSQL文がそのまま検索に使用できる時の流れは書いていますが、検索条件をプログラム内で変更したい場合も当然出てきます。その場合の方法です。説明のため、またKigenの一部ソースを引っ張ってきて手を加えています。

NSInteger level1 = 1;
sqlite3_stmt *st;
const char *sql2 = "SELECT pk FROM kigen WHERE level1=?";
if (sqlite3_prepare_v2(database, sql2, -1, &st, NULL) == SQLITE_OK) {
NSLog(@"sql文の準備完了");
sqlite3_bind_int(st, 1, level1);
while (sqlite3_step(st) == SQLITE_ROW) {
 
以前の例とどこが違うかというと、まずSQL文の中に?があります。これが後で変数が放り込まれる部分です。SQL文ではkigenテーブルからlevel1列の内容が?である行でpk列に入っている内容を表示するように指示しています。そして次に違うのがsqlite3_bind_intという命令が準備が終わって実際に検索を行うまでの間に挿入されている点です。この命令で、stがポインタになっているSQL文の1個目の?にlevel1という整数の変数を代入するように指示しています。?が何個もある場合には、その数だけsqlite3_bind_intなどの命令が入るわけです。
 

データベースファイルの作成方法 その3 データの入力

2008年11月22日
 作成の最終段階、実際のデータ入力です。ホームのファイルは前回のまま残っているものとします。

  1. 前回と同様、ターミナルでsqlite3 test.sqlと入力しEnterを押します。
  2. insert into namae(pk,name) values (1,'abc');と入力しEnterを押します。nameとして"abc"という値を持つ行が作られます。
  3. 同様にinsert into namae(pk,name) values (2,'xyz');と入力しEnterを押します。さらに"xyz"という値を持つ行が作られました。
  4. では確認してみましょう。select * from namae;と入力してEnterを押してください。これで2行のデータが表示されていれば、入力は成功しています。
  5. .quitと入力しEnterを押して終了します。

ものすごく簡略化していますが、基本的なデータファイルの作成方法はこんな感じです。自分で使いたいデータベースの形によって、テーブルに含める列の数やデータ型等を工夫してみましょう。作成したデータファイルはホームから自分のプロジェクトフォルダにコピーして、プロジェクトのリソースにはXcode上で追加>既存のファイル...で組み込みます。

ちなみに、上の例でpkに指定しているprimary keyというのは、各行で決して重複した値をとれないように制限を設ける設定です。上の例でもしxyzを入れるとき、pkを1にしていたらabcの行とかぶるのでエラーが出て入力できません。この設定は、データベース内のある行の値を変更したいという場合に利用できます。変更を行う場合、複数行を同時に変更するような命令は受け付けられません。そこで確実にデータベースの1行だけを狙い撃ちで指定できるprimary key設定された列があると便利なのです。なお複数行の変更は該当するpkのリストを作り、1行ずつ変更します。

データベースファイルの作成方法 その2 テーブルの作成

2008年11月22日
 前回は何もしていないので、今度はテーブルを作成します。

  1. 前回同様にターミナルを起動します。
  2. 今度はsqlite3 test.sqlと入力してEnterを押します。test.sqlを作りたいことが伝わります。
  3. create table namae(pk int primary key, name char);と入力してEnterを押します。これでnamaeという名称のテーブルが作られます。pk int primary keyで、テーブルに行ごとに別の整数を持つpkという名称の列を作ること、name charでnameという名称の文字列を格納する列を作ることを指示しています。データの型には他に浮動小数点型のrealなどがあります。
  4. 確認のため、.tableと入力してEnterを押します。namaeと表示されていれば、テーブルが作られています。
  5. 次に.schema namaeと入力してEnterを押します。namaeテーブルを作成した時の命令が表示されます。これでテーブル内の列にどのようなデータ型を指定したか確認できます。
  6. 今回はここまで、ということで.quitと入力しEnterを押します。

ファイルはホームに作られています。Finderで確認してみてください。ファイルはテーブルを作った時点で作成されます。

データベースファイルの作成方法 その1 SQLite3の起動

2008年11月22日
 データベースファイルを作成する方法です。まずは基礎の基礎、SQLite3の起動と終了から。

  1. Finderで場所からアプリケーションを選びます。
  2. ユーティリティのターミナルを選びます。
  3. sqlite3と入力しEnterを押します。SQLite Version 〜と表示されれば起動成功です。
  4. .quitと入力しEnterを押すと終了します。
  5. ターミナルを閉じます。

iPhone SDKがインストールされている環境なら追加でインストール等を行わなくてもSQLite3は起動するはずですが、念のための確認です。

データベースのオープンと検索の基本

2008年11月22日
データベースのファイルが作れたら、まずそれを開きます。以下の例はKigenのソースを元に解りやすいように一部を書き換えたものです。何をやっているかというと、カテゴリリスト画面のUITableViewに表示するデータを格納する配列の作成です。ファイルを開いて、検索して、次の検索ができるように解放するところまでで、ファイルを閉じるところは含まれていません。ファイルはプログラム自体が終了するところで閉じるからです。

// lv1はカテゴリ1行ごとのデータ(下に出てくるNamaeというデータクラス)を格納する配列で、
// 本当はクラス内で宣言しています

NSMutableArray *lv1;
// databeseはデータベースのポインタで、これも本当はクラス内で宣言してます
sqlite3 *database;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"mydatabase.sql"];
// mydatabase.sqlに自分で用意するデータベースファイル名を入れてください
if (sqlite3_open([path UTF8String], &database) == SQLITE_OK) {
// データベースファイルを開くことに成功しましたので、SQL文を構築します
// namaeというテーブルのデータでlevel2という列が-1になっている行から
// pkという列にあるデータ(重複不可能な行番号)を取り出します
const char *sql = "SELECT pk FROM namae WHERE level2=-1";
// SQL文を保持するポインタを作ります
sqlite3_stmt *statement;
// SQLで検索を実行する前準備です
if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK) {
// 準備が完了したので、実際に検索を実行します
// 検索条件に合う行があればSQLITE_ROWが返りループし続けます
while (sqlite3_step(statement) == SQLITE_ROW) {
// pkの値を変数primaryKeyに代入します。
int primaryKey = sqlite3_column_int(statement, 0);
// Namaeというデータクラスを記憶する場所を確保します
// 確保されたデータクラスは自身で行に含まれている残りのデータを取り出します
Namae *namae = [[Namae alloc] initWithPrimaryKey:primaryKey
database:database];
// 作成したNamaeクラスを配列に加えます
[lv1 addObject:namae];
// namaeという名前のポインタはもう不要なので解放します
[namae release];
} // ここまでが検索で該当する行がある限り繰り返されます
}
// 検索が終わったのでSQL文を解放します
sqlite3_finalize(statement);
} else {
// 何かエラーが起きた場合にはデータベースを閉じます
sqlite3_close(database);
NSAssert1(0, @"データベースのオープンに失敗 '%s'.", sqlite3_errmsg(database));
}

データベースのオープンと検索の概要

2008年11月20日
SQLite3データベースの開き方はアップル提供のサンプルSQLite Book Listが参考になります。AppDelegate.mにあるcreateEditableCopyOfDatabaseIfNeededをそのまま再利用することができます。ファイル名を自分がリソースとして加えたデータベースファイルのものに変更するだけです。これでまずデータベースファイルが必ず存在する状態(発見できなければ作成する)にします。

実際にデータベースを開いてSQL文でデータを取り出す操作はinitializeDatabaseが参考になります。基本的な流れとしては、まずファイルをsqlite3_open関数で開いたあと、SQL文を作り、それを準備用の関数に渡します。文の中に変数(”?”と表記した部分)がある場合は、そこの部分に実際の変数を埋め込みます。そして実際に検索を行います。データベースに検索条件に一致するデータがあった場合には、それを順番に読み出します。データの読み出しが終わったらSQL文をデータベースから解放します。

データベースファイルを最終的に閉じる方法はapplicationWillTerminateにあるように、sqlite3_close関数を実行します。ファイルを開いたときと閉じたとき、問題が無い場合はSQLITE_OKが返ってきます。

2008.12.8追記
SQLite Book ListのcreateEditableCopyOfDatabaseIfNeededでやっているのは、ユーザーのデータ用フォルダにファイルが無い場合にリソースのSQLファイルをコピーする動作でした。初回の起動時に行われるだけで、既にユーザーデータがある場合はコピーをしません。そのため、バージョンアップを行ってもユーザーが作ったデータにサンプルデータを上書きしてしまう、というような事態は避けられるようになっています。

SQLite3を利用するには

2008年11月19日
 自分のプログラムでSQLite3を使うには、Frameworksの項目に

libsqlite3.0.dylib

を既存のファイルを追加で加えておきます。場所はフルパスで

/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.1.sdk/usr/lib/libsqlite3.0.dylib

です。実際に命令を行うmファイルに対応したhファイルの頭の部分に

#import <sqlite3.h>

を加えておきます。

2010年1月31日追記:
現在のiPhone SDK 3.1.2では自分でsqlite3データベースを開く以外に、Core Dataを利用して間接的にsqlite3を利用する方法もあります。他の環境で製作したデータベースファイルを持ってくる、といった用途には向きませんが、テーブル同士で連携をさせる場合などは、Xcodeのモデルエディタを用いてグラフィカルなデータベース構築が行えるなどの利点があります。Core Dataについては初めてのCore Data on iPhone(混沌のiPhoneアプリケーション工房、プログラミング内)にて簡単な解説をしていますので、そちらも参考にしてください。
 | HOME |