SQLite C言語向けAPI チートシート

SQLite C言語向けAPI チートシートです。
自分以外の需要があるかどうか不明ですが、頻繁に使うもの、便利そうなものについて逐次メモしていきます。

#### 環境
SQLite:3.8.6
ビルド環境：gcc 4.8.1

#### 必要なもの
[本家ダウンロード](http://www.sqlite.org/download.html)から、ソースコードもしくはWindows用DLLを落としきて利用できるようにしておいてください。ヘッダファイルはソースコードが入っているzipの中にあります。

#### 参考サイト
[本家イントロダクション](http://www.sqlite.org/cintro.html)
[本家リファレンス](http://www.sqlite.org/c3ref/intro.html)
[c/c++でsqliteを使う方法 - ぴょぴょぴょ？-Linuxとかプログラミングの覚え書き-](http://d.hatena.ne.jp/pyopyopyo/20070417/p1)
[「SQLite3」に関するページ - idocsq.net](idocsq.net http://idocsq.net/titles/41)

## データベースの基本的な使用方法
とりあえず、これさえおさえておけば使うことはできる！とうわけで、
DBファイルを開いて、データの挿入と抽出をする方法について記します。

#### DBファイルの開閉
ファイルの開閉は、DBファイル名とDBのアクセス用オブジェクトがあれば行えます。

```c:sqlite3_sample.c
// DBファイル名
char *fileName = "mySQLiteDB";

// DBオブジェクト
sqlite3 *pDB = NULL;
```

```c:sqlite3_sample.c
// DBのオープン
err = sqlite3_open(fileName, &pDB);
if(err != SQLITE_OK){
	printf("OPEN ERR! %d\n", err);

	/* TODO:エラー処理 */
}
printf("OPEN SUCCESS!\n");
```

```c:sqlite3_sample.c
// DBのクローズ
err = sqlite3_close(pDB);
if(err != SQLITE_OK){
	printf("CLOSE ERR! %d\n", err);

	/* TODO:エラー処理 */
}
printf("CLOSE SUCCESS!\n");
```

オプションを使用してDBの開閉を行いたい場合は、[sqlite3_open_v2](http://www.sqlite.org/c3ref/open.html)を使って行えます。

#### テーブルの作成と削除
「テーブルの作成にはこれを使ってください！」といえるような関数が用意されていればよいのですが、そんなことはないのでSQL文をベタ打ちで実行していきます。
SQL文を実行する方法は主に2通りありますが、
テーブルの作成や削除のような使いまわさないSQL文は、[sqlite3_exec()](http://www.sqlite.org/c3ref/exec.html)で実行します。

```c:sqlite3_sample.c
// テーブルの作成
char *errMsg = NULL;
int err = 0;

err = sqlite3_exec(pDB,
	"CREATE TABLE IF NOT EXISTS myTable "
	"(id INTEGER PRIMARY KEY AUTOINCREMENT, "
	"name CHAR(32) NOT NULL)",
	NULL, NULL, &errMsg);

if(err != SQLITE_OK){
	printf("%s\n", errMsg);
	sqlite3_free(errMsg);
	errMsg = NULL;
	/* TODO: エラー処理 */
}
printf("CREATE TABLE!\n");
```

```c:sqlite3_sample.c
// テーブルの削除
char *errMsg = NULL;
int err = 0;

err = sqlite3_exec(pDB,
	"DROP TABLE IF EXISTS myTable",
	NULL, NULL, &errMsg);

if(err != SQLITE_OK){
	printf("%s\n", errMsg);
	sqlite3_free(errMsg);
	errMsg = NULL;
	/* TODO: エラー処理 */
}
printf("DROP TABLE!\n");
```

sqlite3_exec()の第3引数はコールバック関数、第4引数はコールバック関数の第1引数となりますが、基本的にNULLで問題ありません。

#### データの追加と抽出
データの追加と抽出のような使いまわすクエリ実行には、[sqlite3_prepare()](http://www.sqlite.org/c3ref/prepare.html)と[sqlite3_step()](http://www.sqlite.org/c3ref/step.html)を使います。これらを実行するにはステートメントオブジェクトが必要になります。
sqlite3_prepareでステートメントオブジェクトを用意して、sqlite3_step()でそれを実行するという順番になります。オブジェクトを使い終わったら、[sqlite3_finalize()](http://www.sqlite.org/c3ref/finalize.html)でステートメントオブジェクトを解放します。

```c:sqlite3_sample.c
// ステートメントオブジェクト
sqlite3_stmt *pStmt = NULL;
```

```c:sqlite3_sample.c
// データの追加
// ステートメントの用意
err = sqlite3_prepare_v2(pDB,
	"INSERT INTO myTable (name) VALUES (?)",
	128, &pStmt, NULL);

if(err != SQLITE_OK){
	/* TODO:エラー処理 */
}else{
	int i = 0;
	for(i = 0;i < 5;i++){
		const char name[32];
		snprintf(name, 32, "test%02d", i);

		// ?の部分に値を代入
		sqlite3_bind_text(pStmt, 1, name, strlen(name), SQLITE_STATIC);
		while(SQLITE_DONE != sqlite3_step(pStmt)){}
	}
}

// ステートメントの解放
sqlite3_finalize(pStmt);
printf("ADD DATA!\n");
```

```c:sqlite3_sample.c
// データの抽出
// ステートメントの用意
err = sqlite3_prepare_v2(pDB,
	"SELECT * FROM myTable", 64,
	&pStmt, NULL);

if(err != SQLITE_OK){
	/* TODO:エラー処理 */
}else{
	// データの抽出
	while(SQLITE_ROW == (err = sqlite3_step(pStmt)) ){
		int id = sqlite3_column_int(pStmt, 0);
		const char *name = sqlite3_column_text(pStmt, 1);
		printf("id: %d, name: %s\n", id, name);
	}

	if(err != SQLITE_DONE){
		/* TODO: エラー処理 */
	}
}

// ステートメントの解放
sqlite3_finalize(pStmt);
```