接続したDBにクエリを投げて、以下のような簡単なテーブルを作ってみよう。
日付 | 品目 | 価格 |
---|
以下のサンプルではsqlite3_exec()を使わず、sqlite3_prepare_v2(), sqlite3_step(), sqlite3_finalize()を使ってクエリを投げている。
// vim: set fileencoding=utf-8:
#include <stdio.h>
#include <string.h>
#include <sqlite3.h>
#define DEFAULT_FILENAME "test2.sqlite3"
int main(int argc, char **argv) {
sqlite3 *db = NULL;
int rc;
char *filename = DEFAULT_FILENAME;
// open
if (argc >= 2) filename = argv[1];
rc = sqlite3_open(filename, &db);
if (rc == SQLITE_OK)
printf("sqlite3_open() : OK, db = %p\n", db);
else
printf("sqlite3_open() : NG(%d), db = %p\n", rc, db);
// create table
const char *query = "create table 家計簿(日付 text, 品目 text, 価格 int);";
// query = "creat table 家計簿(日付 text, 品目 text, 価格 int);";
sqlite3_stmt *stmt = (sqlite3_stmt *) 0xdeadbeaf;
rc = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
if (rc == SQLITE_OK)
printf("sqlite3_prepare_v2() : OK, stmt = %p\n", stmt);
else
printf("sqlite3_prepare_v2() : NG(%d), stmt = %p\n", rc, stmt);
if (stmt != NULL) {
rc = sqlite3_step(stmt);
if (rc == SQLITE_DONE)
printf("sqlite3_step() : DONE\n");
else
printf("sqlite3_step() : NG(%d)\n", rc);
}
rc = sqlite3_finalize(stmt);
if (rc == SQLITE_OK)
printf("sqlite3_finalize() : OK, stmt = %p\n", stmt);
else
printf("sqlite3_finalize() : NG(%d), stmt = %p\n", rc, stmt);
// close
rc = sqlite3_close(db);
if (rc == SQLITE_OK)
printf("sqlite3_close() : OK, db = %p\n", db);
else
printf("sqlite3_close() : NG(%d), db = %p\n", rc, db);
return 0;
}
sqlite3_prepare_v2()は、UTF-8の文字列で表現されたクエリから内部形式であるsqlite3_stmt型のオブジェクトを生成するAPI。生成されたオブジェクトの場所は、第4引数で参照渡しするポインタ変数に返してもらう。sqlite3_open()とは異なり、失敗したら何もリソースは確保せず、NULLを返す。
sqlite3_prepare_v2()が生成したsqlite3_stmt型のオブジェクトを実行するのがsqlite3_step()。今回はテーブルを作成しているだけなので、クエリの実行結果としてテーブルが返ってきたりはしない。
使い終わったsqlite3_stmt型のオブジェクトは、sqlite3_finalize()で解放する。引数にNULLを渡しても実害はないようだ。
コメントアウトしているクエリは、わざとタイプミスをしたもの。これを実行するとsqlite3_prepare_v2()がエラーを返す。また、コンパイルした実行バイナリを2度3度実行すると、2回目以降はsqlite3_prepare_v2()がエラーを吐く。既存のテーブルと同じ名前のテーブルを作成しようとするので、失敗すること自体は想定していたが、sqlite3_step()でこけるものだと思っていた。sqlite3_open()かsqlite3_prepare_v2()で、DBに含まれているテーブル名くらいは見ているのかな?
0 件のコメント:
コメントを投稿