このページはhttp://www.sqlite.org/c_interface.htmlを翻訳したものです。 わかりにくい所があれば原文を見てください。 翻訳の最終更新日は 2004/06/07 です。
SQLiteライブラリはC/C++のプログラムから非常に使いやすいように設計されています。 このドキュメントに、C/C++プログラムインタフェースの概要を示します。
SQLiteライブラリを扱うためのインタフェースは3つの中心的な関数と、 1つのopaque型構造体と、戻り値として利用されるいくつかの定数から成り立っています。 中心的なインタフェースは次の通りです:
typedef struct sqlite sqlite; #define SQLITE_OK 0 /* 成功 */ sqlite *sqlite_open(const char *dbname, int mode, char **errmsg); void sqlite_close(sqlite *db); int sqlite_exec( sqlite *db, char *sql, int (*xCallback)(void*,int,char**,char**), void *pArg, char **errmsg );
上記のものは、C/C++プログラムからSQLiteを利用するために必ず覚える必要があるものです。 他にも(下記の)利用可能な関数がありますが、 まずは上記の中心的な関数の説明を行います。
既存のデータベースを開く時や、新しくデータベースを作る時には、 sqlite_open関数を使ってください。 第1引数はデータベースの名前です。 第2引数はデータベースを読み書き可能にするか、 読み取り専用として開くかを決めるための合図になってます。 しかし、現在のバージョンでは無視されます。 第3引数は文字列ポインタへのポインタです。 第3引数がNULLではなく、データベースを開く時にエラーが発生した場合、 malloc()によってメモリが確保され、その領域にエラーメッセージが書き込まれます。 そして、*errmsgがそのエラーメッセージへのポインタとなります。 malloc()を呼んだ関数は、終了時にメモリを解放する義務があります。
SQLiteデータベースの名前は、これから開こうとするデータベースファイルの名前です。 データベースが存在しない場合は、新しく作成し、初期化します。 ファイルが読み取りしか出来ない場合(CD-ROMなどのように)、 SQLiteはデータベースを読み取り専用で開きます。 現在開いているデータベースは、1つのファイルに格納されています。 しかし、SQLコマンドの実行中には、 ロールバックジャーナルや中間的なクエリの結果を保存するために 追加的にテンポラリファイルが作られるかもしれません。
sqlite_open関数の戻り値は、opaque型のsqlite構造体へのポインタです。 このポインタが、同じデータベースを扱うSQL関数への第1引数となります。
ファイルオープンに失敗した場合はNULLが返ります。SQLiteデータベースを閉じたい時は、sqlite_openから受け取ったsqlite構造体へのポインタを引数にして sqlite_close関数を使ってください。
sqlite_exec関数はSQLステートメント/クエリを実行する時に使用します。 この関数の5つの引数は以下の通りです:
コールバック関数は、クエリの結果を受け取るために使用されます。 コールバック関数のプロトタイプ宣言は次の通りです:
int Callback(void *pArg, int argc, char **argv, char **columnNames){ return 0; }
コールバック関数の第1引数は、sqlite_execの第4引数であり、 任意のデータを送るために使用することが出来ます。 第2引数は、クエリの結果で得られたカラムの数です。 第3引数は、結果の文字列へのポインタの配列です。 NULLポインタのデータベースでは、NULL値が返されます。 NULL値と空の文字列は違うことに注意してください。 i番目の要素が空の文字列だった場合は:
argv[i][0] = 0
しかし、i番目の要素がNULLだった場合は:
argv[i] == 0
第4引数の0〜argc-1までの要素はカラム名になります。 pragma SHOW_DATATYPESがonの時(デフォルトではoff)、 第4引数のargc〜argc*2-1までの要素はカラムのデータ型になります。
pragma EMPTY_RESULT_CALLBACKSがonで クエリの結果が空になった時、第3引数(argv)を0にするために一度だけ呼ばれます。 つまり
argv == 0
結果が空でなければ、 結果のカラムの数や名前を得るために 第2引数(argc)と第4引数(columnNames)を使うことが出来ます。 デフォルトの動作では、結果が空になった時はコールバック関数を呼びません。
通常はコールバック関数は0を返すべきです。 0以外の値を返した場合は、クエリはすぐにアボートされ、 sqlite_execはSQLITE_ABORTを返します。
sqlite_exec関数は通常はSQLITE_OKを返します。 しかし、上手く動作しなかった場合にはエラーのタイプを示す値を返します。 以下に戻り値の一覧を示します:
#define SQLITE_OK 0 /* 成功 */ #define SQLITE_ERROR 1 /* SQLエラー、もしくはデータベースが見つかりません */ #define SQLITE_INTERNAL 2 /* SQLiteの内部ロジックエラー */ #define SQLITE_PERM 3 /* アクセス権がありませn */ #define SQLITE_ABORT 4 /* コールバック関数がアボートを要求した */ #define SQLITE_BUSY 5 /* データベースがロックされています */ #define SQLITE_LOCKED 6 /* テーブルがロックされています */ #define SQLITE_NOMEM 7 /* malloc()に失敗しました */ #define SQLITE_READONLY 8 /* 読み取り専用のデータベースに書き込もうとしました */ #define SQLITE_INTERRUPT 9 /* オペレーションがsqlite_interrupt()によって終了された */ #define SQLITE_IOERR 10 /* ディスクI/Oエラー */ #define SQLITE_CORRUPT 11 /* データベースディスクイメージがmalformed */ #define SQLITE_NOTFOUND 12 /* (Internal Only) テーブルかレコードが見つかりません */ #define SQLITE_FULL 13 /* データベースにはこれ以上追加できません */ #define SQLITE_CANTOPEN 14 /* データベースファイルが開けませんでした */ #define SQLITE_PROTOCOL 15 /* データベースロックプロトコルエラー */ #define SQLITE_EMPTY 16 /* (Internal Only) テーブルが空でした */ #define SQLITE_SCHEMA 17 /* データベースのスキーマが変更されました */ #define SQLITE_TOOBIG 18 /* Too much data for one row of a table */ #define SQLITE_CONSTRAINT 19 /* contraint violationのため強制終了しました */ #define SQLITE_MISMATCH 20 /* データ型が間違ってます */ #define SQLITE_MISUSE 21 /* ライブラリの使い方が間違ってます */ #define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ #define SQLITE_AUTH 23 /* Authorization denied */ #define SQLITE_ROW 100 /* sqlite_step() has another row ready */ #define SQLITE_DONE 101 /* sqlite_step() has finished executing */
以下に戻り値の詳細を示します:
sqlite_exec関数はSQLiteデータベースから検索するための唯一の方法でした。 しかし、結果を得るためにコールバック関数を使うのは面倒です。 そのような理由で、SQLite version 2.7.7からはコールバック関数を使わずにアクセスできる 2番目のインタフェースが作られました。
新たなインタフェースではsqlite_execを分割してつくられた3つの関数を使います。
typedef struct sqlite_vm sqlite_vm; int sqlite_compile( sqlite *db, /* 開いているデータベース */ const char *zSql, /* コンパイルされるSQLステートメント */ const char **pzTail, /* OUT: コンパイルされていない次のSQLステートメント */ sqlite_vm **ppVm, /* OUT: zSqlを実行するための仮想マシン */ char **pzErrmsg /* OUT: エラーメッセージ */ ); int sqlite_step( sqlite_vm *pVm, /* 実行するための仮想マシン */ int *pN, /* OUT: 得られたカラムの数 */ const char ***pazValue, /* OUT: カラムデータ */ const char ***pazColName /* OUT: カラム名と型 */ ); int sqlite_finalize( sqlite_vm *pVm, /* 終了させるための仮想マシン */ char **pzErrMsg /* OUT: エラーメッセージ */ );
一連の流れとしては、 1つのSQLステートメントをコンパイルするためにsqlite_compileが使用され、 各ローを出力するためにsqlite_stepが複数回呼び出され、 最後にSQLが終了した後の後始末のためにsqlite_finalizeが呼ばれます。
sqlite_compileの(第2引数によって設定された)SQLステートメントの"コンパイル"し、 そのステートメントが実行可能な仮想マシンを生成します。 多くの関数と同じように、第1引数はsqlite_openによって得られたsqlite構造体へのポインタです。
仮想マシンへのポインタは第4引数に格納されます。 仮想マシンを保持するために必要なメモリは、動的に確保します。 メモリリークを避けるために、その関数では作業が終わった後に 仮想マシン上でsqlite_finalizeを呼んでください コンパイル中にエラーが発生した場合は、第4引数にNULLがセットされます。
コンパイル中にエラーが発生した場合、 malloc()によって領域へのポインタが第5引数にセットされ、 その領域にエラーメッセージが書き込まれます。 第5引数がNULLならエラーメッセージはありません。 NULLでなければ、sqlite_freememを呼び出すことで、 エラーメッセージのために確保された領域を解放してください。
第2引数に2つ以上のSQLステートメントが含まれていた場合、 最初のSQLステートメントしかコンパイルされません。 (これは、全てのSQLステートメントを実行するsqlite_execの動作とは異なっています。) 第3引数は、次のSQLステートメント文字列へのポインタとなります。 もし第2引数に1つしかSQLステートメントが含まれていなければ、 第3引数には第2引数の終端である'\0000'がセットされます。
成功した場合、sqlite_compileはSQLITE_OKを返します。 そうでなければ、エラーコードを返します。
sqlite_compileによって仮想マシンが生成されると、 次は実行するためにsqlite_stepが何度か呼ばれます。 最後のsqlite_stepの呼び出し以外では、結果の1つのローを返します。 第3引数によって指定されたポインタは、カラム値へのポインタの配列へのポインタとなります。 第4引数はカラム名とデータ型へのポインタの配列へのポインタとなります。 sqlite_stepの第4引数と第2引数は、 sqlite_execのコールバック関数の 第4引数と第2引数と同じような情報です。 ただし、sqlite_stepの第4引数には、pragma SHOW_DATATYPESの状態にかかわらず、 常にカラムのデータ型情報が含まれています。
呼び出されたsqlite_stepは、 そのステップの間に何が起こったかを示すint型コードを返します。 そのコードには、SQLITE_BUSY、SQLITE_ROW、SQLITE_DONE、SQLITE_ERROR、SQLITE_MISUSEなどがあります。
データベースが別のプロセスやスレッドにロックされて開けない時は、 sqlite_stepはSQLITE_BUSYを返します。 関数はロックが解除されることを期待して、 実行可能な別の処理を行うか、 または少しの間スリープさせておき、 後で再び実行するべきです。 これは何度でも繰り返すことが可能です。
結果データの別のローが利用可能なときは常にsqlite_stepはSQLITE_ROWを返します。 このローデータは文字列型ポインタの配列として格納され、 第2引数がこの配列へのポインタとなります。
全ての作業が完了すると、sqlite_stepは SQLITE_DONEかSQLITE_ERRORのどちらかを返します。 SQLITE_DONEはステートメントが成功して完了したことを表し、 SQLITE_ERRORはランタイムエラーがあったことを表します。 (エラーの詳細はsqlite_finalizeから得られます。) SQLITE_DONEかSQLITE_ERRORが返された後に、 再びsqlite_stepを呼ぼうとするのは間違いです。
sqlite_stepがSQLITE_DONEかSQLITE_EERORを返した時、 SQLITE_ROWが返ってきた場合のように、 *pNと*pazColNameの値にはそれぞれ、結果のカラム数とカラム名がセットされます。 これによって、結果が空の時でも呼び出しコードがカラム名や データ型を得ることが出来るようになります。 SQLITE_DONEかSQLITE_ERRORが返ってきた時には、*pazValueは常にNULLになります。 実行されているSQLステートメントが(INSERTやUPDETEのような)結果を返さないものの場合、 *pNには0がセットされ、*pazColNameにはNULLがセットされます。
不適当にsqlite_stepを呼び出そうとすると、 SQLITE_MISUSEを返します。 これは2つのスレッドから同時に同じ仮想マシンでsqlite_step()を呼び出そうとしたり、 SQLITE_DONEやSQLITE_ERRORが返された後に再び呼び出そうとしたり、 無効な仮想マシンへのポインタをsqlite_step()に送ったときに起こります。 エラーを探すために、SQLITE_MISUSEという戻り値に頼ってはいけません。 インタフェースの誤用が発見されなくなり、プログラムがクラッシュする可能性があります。 SQLITE_MISUSEはデバッグを簡単にするためだけに存在しています。 (事故が起こる前に間違った使い方を検知するため。) 誤用検知ロジックが全てのケースで上手く動作する保証はありません。
sqlite_compileで作られたすべての仮想マシンは、 最終的にはsqlite_finalizeに渡す必要があります。 sqlite_finalize()は仮想マシンが使っていたメモリとリソースを解放します。 sqlite_finalize()の呼び出しを忘れると、リソースリークが発生してしまいます。
sqlite_finalize関数は、仮想マシンが実行したSQLオペレーションの 結果を示すコードを返します。 sqlite_finalizeの戻り値は、同じSQLがsqlite_execで実行された時の戻り値と同じです。 返されるエラーメッセージも同じです。
sqlite_stepを一度も実行せずにsqlite_finalizeを呼んでも問題ありません。
SQLiteを使うために必要なものは、1章で説明した3つの中心的な関数だけです。 しかし、他にも有用なインタフェースを提供する関数があります。 拡張関数には次のようなものがあります:
int sqlite_last_insert_rowid(sqlite*); int sqlite_changes(sqlite*); int sqlite_get_table( sqlite*, char *sql, char ***result, int *nrow, int *ncolumn, char **errmsg ); void sqlite_free_table(char**); void sqlite_interrupt(sqlite*); int sqlite_complete(const char *sql); void sqlite_busy_handler(sqlite*, int (*)(void*,const char*,int), void*); void sqlite_busy_timeout(sqlite*, int ms); const char sqlite_version[]; const char sqlite_encoding[]; int sqlite_exec_printf( sqlite*, char *sql, int (*)(void*,int,char**,char**), void*, char **errmsg, ... ); int sqlite_exec_vprintf( sqlite*, char *sql, int (*)(void*,int,char**,char**), void*, char **errmsg, va_list ); int sqlite_get_table_printf( sqlite*, char *sql, char ***result, int *nrow, int *ncolumn, char **errmsg, ... ); int sqlite_get_table_vprintf( sqlite*, char *sql, char ***result, int *nrow, int *ncolumn, char **errmsg, va_list ); char *sqlite_mprintf(const char *zFormat, ...); char *sqlite_vmprintf(const char *zFormat, va_list); void sqlite_freemem(char*); void sqlite_progress_handler(sqlite*, int, int (*)(void*), void*);
上記の関数は全て"sqlite.h"ヘッダファイルに定義されています。
SQLiteテーブルの全てのローはユニークなint型keyを持っています。 テーブルがINTEGER PRIMARY KEYというカラムを持っている場合、 そのカラムがkeyとして利用されます。 持っていない場合は、keyはユニークなint型の値になります。 keyは、SELECTステートメントでアクセスすることが出来たり、 "ROWID"、"OID"、"_ROWID_"のどれかを使ったWHEREやORDER BY節で使用することが出来ます。
INTEGER PRIMARY KEYを持っていないテーブルにINSERTを行う時、 あるいはINTEGER PRIMARY KEYを持っているが、VALUES節でINSERTする値が設定されていない時に、 keyが自動的に生成されます。 sqlite_last_insert_rowid APIを使うことで、 最後にINSERTステートメントを行ったkeyの値を得ることが出来ます。
sqlite_changes API関数は、最後のquiescentなデータベースから、 挿入、削除、修正が行われたローの数を返します。 "quiescent"なデータベースとは、未解決のsqlite_execの呼び出しがなく、 sqlite_finalizeによって終了されていない仮想マシンが存在していない時のことです。 共通の使い方として、最後に呼んだsqlite_execによって変更された数か、 最後に呼んだsqlite_compilieから今までに変更された数を返します。 しかし、sqlite_execがネストしたり (すなわち、あるsqlite_execのコールバック関数で別のsqlite_execが呼ばれたり)、 既にVMが存在している時に別のVMを作ろうとsqlite_compileが呼ばれたりした場合には、 sqlite_changesによって返される値は複雑になります。 ROLLBACKやABORTによって取り消された場合には記録されます。 しかし、DROP TABLEによって削除されるローはカウントされません。
SQLiteは(WHERE節のない)"DELETE FROM table"というコマンドを、 テーブルを削除してから作り直すことで実行します。 この方法は、テーブル内の各要素をそれぞれ削除する方法よりも非常に早いです。 しかしこれは、テーブルに入っていた要素の数にかかわらず、 sqlite_changesの戻り値が0になることを意味しています。 削除された要素数が必要なら、代わりに"DELETE FROM table WHERE 1"を使ってください。
sqlite_get_table関数は、連続的なコールバック関数からの情報や、 malloc()で確保されたメモリに書き込まれた情報を集めるための、 sqlite_execのラッパ関数です。 これは、一度の関数呼び出しによって、 データベースクエリの全ての結果を受け取ることが出来る便利な関数です。
sqlite_get_tableから得られる重要なresultは、文字列へのポインタの配列です。 There is one element in this array for each column of each row in the result. 結果が空の時はNULLポインタになります。 標準的なデータに加えて、 配列の最初にresultのカラム名を含んだローが追加されます。
例えば、次のクエリの場合
SELECT employee_name, login, host FROM users WHERE logic LIKE 'd%';
このクエリは、loginが"d"から始まる全ての従業員のname、login、hostを返します。 このクエリがsqlite_get_tableに送られた場合、 このような結果になるかもしれません:
nrow = 2 ncolumn = 3 result[0] = "employee_name" result[1] = "login" result[2] = "host" result[3] = "dummy" result[4] = "No such user" result[5] = 0 result[6] = "D. Richard Hipp" result[7] = "drh" result[8] = "zadok"
"dummy"レコードの"host"がNULLなので、 result[] 配列にNULLが含まれていることに注意してください。
クエリが空の結果になる場合、 標準のsqlite_get_tableによって、 nrowに0をセットされ、resultにNULLがセットされます。 しかし、pragma EMPTY_RESULT_CALLBACKSがonの時は、 resultにはカラム名が追加されます。 たとえば、結果が空になるこのクエリの場合では:
SELECT employee_name, login, host FROM users WHERE employee_name IS NULL;
デフォルトでは、以下のような結果になります:
nrow = 0 ncolumn = 0 result = 0
しかし、pragma EMPTY_RESULT_CALLBACKSがonの時は次のような結果になります:
nrow = 0 ncolumn = 3 result[0] = "employee_name" result[1] = "login" result[2] = "host"
sqlite_get_tableでは情報を書き込むためのメモリをmalloc()で確保しています。 しかし、このメモリを直接解放しようとしてはいけません。 代わりに、情報が必要なくなったときに、 sqlite_free_tableを呼び出して解放してください。 (結果が空の時に返される)NULLポインタを引数にして sqlite_free_tableを呼び出しても問題ありません。
sqlite_get_table関数は、 sqlite_execと同じint型の戻り値を返します。
sqlite_interrupt関数は 出来るだけ早く現在のデータベースオペレーションを中断させるために、 別のスレッドやシグナルハンドラから呼ぶことが出来ます。 この結果、データベースオペレーションを行っているsqlite_exec関数 (あるいは類似関数)は、SQLITE_INTERRUPTを返します。
次のSQLiteのインタフェース関数は、 文字列がcomplete SQLステートメントであるかどうかの テストのために使用される便利な関数です。 sqlite_complete関数がtrueを返した場合、 その引数はcomplete SQLステートメントです。 そのステートメントのシンタックスが正確である保障はありませんが、 少なくともステートメントはcompleteです。 sqlite_completeがfalseを返した場合、 もっと多くのテキストがSQLステートメントをcompleteにするために要求されます。
sqlite_complete関数の機能によって、 SQLステートメントがセミコロンで終了していればcompleteです。
sqliteコマンドライン・ユーティリティは、 sqlite_execを呼ぶ必要があるときを知るために、 sqlite_complete関数を利用します。 入力された文字列を受け取った後、 バッファ内の全ての入力に対してsqlite_completeを呼びます。 sqlite_completeがtrueを返した場合、 sqlite_execが呼ばれ、入力バッファはリセットされます。 falseを返した場合は、プロンプトはcontinuationプロンプトに変更され、 テキストの別の文字列が読まれて入力バッファに追加されます。
SQLiteライブラリは、ライブラリのバージョン番号を含んだ sqlite_versionという名前のconst文字列を提供します。 ヘッダファイルには、同じ情報を持つマクロのSQLITE_VERSIONが含まれています。 sqlite_versionとSQLITE_VERSIONを比較することで、 ヘッダファイルとライブラリのバージョンが一致するかどうかを確認できます。
デフォルトでは、SQLiteは8ビット固定のエンコード(iso8859)を使用します。 しかし、utf8を利用可能にするスクリプトを追加すれば、 サイズ可変のエンコードUTF-8を利用できます。 エンコードによって、LIKEとGROBオペレータやLENGTH()とSUBSTR()関数に違いが生じます。 静的な文字列sqlite_encodingには、ライブラリがどのようにコンパイルされたかを示す "UTF-8"もしくは"iso8859"がセットされます。 補足として、sqlite.hの中で適切にSQLITE_UTF8か SQLITE_ISO8859のマクロを定義してください。
SQLiteでは、ランタイムによってエンコードの変換ができないことに注意してください。 これはコンパイルするときのオプションでしか変更できません。 sqlite_encoding文字列は、ライブラリがどのようにコンパイルされたかを示します。
sqlite_busy_handler関数は、SQLiteデータベースを開く時に使う ビジーコールバック関数を登録するために使います。 ビジーコールバック関数は、ロックされたデータベースを開こうとした時に呼ばれます。 このコールバック関数では、ロックが解除されるのを待つ間に、 他の実行可能な動作をさせるか、スリープさせると良いでしょう。 コールバック関数が0以外を返した場合は、 SQLiteは再度データベースを開こうとし、 開けなければまた繰り返します。 0を返した場合は、現在のオペレーションが中断され、 SQLITE_BUSYを返します。
sqlite_busy_handlerへの引数は、 sqlite_openの戻り値のopaque型sqlite構造体へのポインタと、 ビジーコールバック関数へのポインタと、 ビジーコールバック関数へ第1引数として渡される汎用ポインタとなります。 ビジーコールバック関数に渡す3つの引数は: sqlite_busy_handlerの第3引数だった汎用ポインタと、 データベーステーブルの名前か、またはライブラリが開こうとしているindexと、 データベーステーブルかindexへアクセスしようと挑戦した回数です。
スリープさせるためにビジーコールバック関数を使いたい場合には、 SQLiteライブラリではsqlite_busy_timeoutという便利な関数が提供されています。 sqlite_busy_timeout関数への第1引数はデータベースへのポインタ、 第2引数は単位がミリセカンドのint型の値です。 sqlite_busy_timeが実行された後、 SQLiteライブラリはロックが解除されるのを待つために、 SQLITE_BUSYを返す前に、最低でも指定された秒の間は待機状態になります。 0[ms]が指定されていた場合は、デフォルトの動作に戻ります。
4つのユーティリティ関数
は、sqlite_execやsqlite_get_tableと 同じようなクエリの実行機能を提供します 違いとしては、第2引数でcomplete SQLステートメントを実行する代わりに、 4つの_printf関数ではprintf形式ののformat文字列を使います。 実行されるSQLステートメントは、このformat文字列と、 関数呼び出し時に後ろにつける追加的な引数から生成されます。
sprintfの代わりに、SQLiteのprintf関数を使うことには2つの利点があります。 まず1つ目は、静的バッファでのオーバーフローが起こりません。 SQLiteのprintf関数は生成されたSQLステートメントに 必要なメモリを自動的に確保(そして解放)します
2つ目の利点は、sprintfには無かった2つの新しいformatオプションがあることです。 これは文字列リテラルをサポートするために作られました。 %q formatオプションは%s に良く似た動作をします。 引数リストからNULLで終わる文字列を読み、そして挿入します。 %sとの違いとしては、%qでは全てのシングルクォート(')を('')に置き換えます。 シングルクォートは文字列の端を意味していて、それを回避する効果があります。 これと良く似た%Q formatオプションでは: 引数がNULLの時に、結果の文字列がシングルクォートなしのNULLになります。
次の例を考えてみて下さい。 ユーザの入力から文字列が得られた時に、 データベースに文字列をINSERTしようしていると仮定してください。 変数zStringにその文字列がセットされると仮定してください。 挿入を行うコードは以下のようになるかもしれません:
sqlite_exec_printf(db, "INSERT INTO table1 VALUES('%s')", 0, 0, 0, zString);
zStringが"Hello"のような文字列を持つ場合、 このステートメントは上手く実行されるでしょう。 しかし、ユーザの入力が"Hi y'all!"という文字列だったと仮定してください。 SQLステートメントは次のように生成されました。
INSERT INTO table1 VALUES('Hi y'all')
これは"y'all"のアポストロフィのせいでvalid SQLではありません。 %sの代わりに%qを使うと、このようになります:
sqlite_exec_printf(db, "INSERT INTO table1 VALUES('%q')", 0, 0, 0, zString);
生成されるSQLは次のようになるでしょう:
INSERT INTO table1 VALUES('Hi y''all')
この結果、アポストロフィの問題は回避され、正しいSQLステートメントになります。 シングルクォートを含んでいるかもしれないデータから、急いでSQLを生成する場合には、 SQLiteのprintf関数と%qオプションを使ったほうが良いでしょう。
%qの代わりに%Qを使った場合はこのようになります:
sqlite_exec_printf(db, "INSERT INTO table1 VALUES(%Q)", 0, 0, 0, zString);
そして、生成されるSQLは次のようになります:
INSERT INTO table1 VALUES('Hi y''all')
zStringがNULLの時に生成されるSQLは次のようになります:
INSERT INTO table1 VALUES(NULL)
上記の_printf()関数の全ては、次の2つの関数から構築されています。
char *sqlite_mprintf(const char *zFormat, ...); char *sqlite_vmprintf(const char *zFormat, va_list);
sqlite_mprintf()関数は標準ライブラリのsprintf()と同じような動作をします。 ただし、malloc()で得られたメモリに結果を書き込み、そのポインタを返す所は違います。 さらに、sqlite_mprintf()では上で説明した%qと%Qが使えます。 sqlite_vmprintf()はvarargsバージョンの同じ関数です。 これらの関数が返した文字列へのポインタは、 sqlite_freemem()を呼び出して解放してください。
sqlite_progress_handler()関数は、 sqlite_exec()やsqlite_step()や様々なラッパ関数が長時間実行中の間、 周期的にSQLiteデータベースから呼び出されるコールバック関数を登録することが出来ます。
コールバック関数は、すべてのN個の仮想マシンの操作から呼び出すことが出来て、 Nはsqlite_progress_handler()の第2引数となります。 第3引数と第4引数は、コールバック関数へのポインタと、 コールバック関数への第1引数となるvoid型のポインタです。
仮想マシン操作の実行にかかる時間は、いろいろな要素に左右されます。 1GHzのPCでの典型的な値は、毎秒に500,000〜3,000,000回となっていますが、 クエリによってはもっと早かったり遅かったりすることもあります。 よって、仮想機械を使ったバックグラウンドでの作業の予測を立てることは難しいです。 それよりも、予定よりも比較的頻繁に(毎秒1000命令とか)に コールバック関数を呼んだほうがいいでしょう。 また、外部でタイマーを使った関数を使って、 バックグラウンドの作業を実行すべきかどうか決めさせると良いでしょう。
バージョン2.4.0から、SQLiteではC言語のコードによって 拡張されたSQL言語が使えるようになりました。 次のようなインタフェースが利用されます:
typedef struct sqlite_func sqlite_func; int sqlite_create_function( sqlite *db, const char *zName, int nArg, void (*xFunc)(sqlite_func*,int,const char**), void *pUserData ); int sqlite_create_aggregate( sqlite *db, const char *zName, int nArg, void (*xStep)(sqlite_func*,int,const char**), void (*xFinalize)(sqlite_func*), void *pUserData ); char *sqlite_set_result_string(sqlite_func*,const char*,int); void sqlite_set_result_int(sqlite_func*,int); void sqlite_set_result_double(sqlite_func*,double); void sqlite_set_result_error(sqlite_func*,const char*,int); void *sqlite_user_data(sqlite_func*); void *sqlite_aggregate_context(sqlite_func*, int nBytes); int sqlite_aggregate_count(sqlite_func*);
sqlite_create_function()インタフェースはregular関数を作成するために使われます。 また、sqlite_create_aggregate()はaggregate関数を作成するために使われます。 どちらの関数でも、変数dbは登録されている関数によって開かれた SQLiteデータベースです。 変数zNameは、新しく作る関数の名前です。 変数nArgは、引数の数です。 pUserData is a pointer which is passed through unchanged to the C implementation of the function. どちらの関数でも、成功すれば0が返り、エラーが発生すると0以外が返ります。
関数名の文字列の長さが255文字を越えてはいけません。 255文字を越えた関数を作ろうとすると、エラーが返されます。
regular関数について。 xFuncコールバック関数は、各関数を呼び出すために1度呼ばれます。 xFuncのインプリメンテーションは、結果を返すために、 sqlite_set_result_...インプリメンテーションの中の1つを呼び出すべきです。 sqlite_user_data()関数では、 関数が登録された時に渡されたpUserDataポインタを検索することが出来ます。
aggregate関数について。 xStepコールバック関数は結果の各ローのために1度呼ばれ、 最終的な答えの計算が終わるとxFinalizeが呼ばれます。 xStep関数は、SQL関数の特別なインスタンスのためのユニークなメモリを確保するために、 sqlite_aggregate_context()インタフェースを利用することが出来ます。 xFinalizeが呼ばれた後で、このメモリは自動的に削除されます。 sqlite_aggregate_count()を使うと、 aggregateにいくつのローが送られたのかが分かります。 xFinalizeコールバック関数には、 aggregateの最終的な結果をセットさせるためのsqlite_set_result_...インタフェースを呼ぶべきです。
プリプロセッサマクロでTHREADASAFEに1をセットしてからSQLiteをコンパイルすると、 同じ時に同じプロセスの2つ以上のスレッドからSQLiteを使用しても安全になります。 しかし、各スレッドがそれぞれsqlite_openから受け取った別のポインタを持つべきです。 同じ時に同じsqlite*型ポインタに2つ以上のスレッドからアクセスしようとすることは、 安全ではありません。
ウェブサイト上で利用可能なようにプリコンパイルされたSQLiteライブラリでは、 UnixバージョンのライブラリではTHREADSAFEはoffの状態でコンパイルされていますが、 Windowxバージョンのライブラリではonの状態でコンパイルされています。 もしも変更したい場合には、再コンパイルしてください。
Unixで動かす場合、fork()システムコール中にsqlite*型ポインタを子プロセスに渡してはいけません。 子プロセスはfork()の後にデータベースのコピーから自分用に開くべきです。
SQLite C/C++インタフェースをどのように利用することができるかの例については、 ソースツリーのsrc/shell.cのソースコードを参照してください。 SQliteに関する補足情報はsqlite.htmlから調べることが出来ます。 SQLiteのTclインタフェースについては、ソースファイルsrc/tclsqlite.cを参照してください。
最終更新日 2004/06/01 10:01:25