SQLite 以 C 語言介面(API)為核心,所有高階語言的驅動程式皆建構於此。本文深入解析 sqlite3_open、sqlite3_exec、回調函數機制、sqlite3_get_table 非回調查詢,以及事務控制,並提供可直接編譯執行的完整範例碼。
所有資料庫操作圍繞 sqlite3* 指標。sqlite3_open() 會為其配置記憶體,後續所有 API 均需傳入此指標;sqlite3_close() 釋放資源。
int sqlite3_open(const char *filename, sqlite3 **ppDb);
filename:資料庫檔案路徑(不存在會自動建立)ppDb:輸出參數,接收配置好的 sqlite3*SQLITE_OK 代表成功int sqlite3_close(sqlite3 *db);
#include "sqlite3.h"
int main() {
sqlite3 *db = NULL;
int rc = sqlite3_open("..\\test\\testDatabase.db", &db);
if (rc != SQLITE_OK) return -1;
// ... 資料庫操作 ...
sqlite3_close(db);
return 0;
}
int sqlite3_exec(
sqlite3 *db,
const char *sql,
int (*callback)(void*,int,char**,char**),
void *arg,
char **errmsg
);
| 參數 | 說明 |
|---|---|
| db | sqlite3_open 回傳的指標 |
| sql | 以 \0 結尾的 SQL 字串 |
| callback | 查詢每一列呼叫一次;INSERT/DELETE 可傳 NULL |
| arg | 使用者自訂指標,透傳給 callback |
| errmsg | 錯誤訊息輸出(雙重指標) |
typedef int (*sqlite3_callback)(void *arg, int nCol, char **colVal, char **colName);
nCol:欄位數colVal:一維陣列,依序存放各欄位值(字串)colName:對應欄位名稱// 回調:列印每一列
int printRow(void *arg, int nCol, char **val, char **name) {
for (int i = 0; i < nCol; ++i)
printf("%s = %s\n", name[i], val[i] ? val[i] : "NULL");
puts("");
return 0;
}
int main() {
sqlite3 *db; char *err = NULL;
sqlite3_open("test.db", &db);
// 建表
sqlite3_exec(db,
"CREATE TABLE t(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);",
NULL, NULL, &err);
// 新增
sqlite3_exec(db, \"INSERT INTO t(name) VALUES('Alice')\", NULL, NULL, &err);
sqlite3_exec(db, \"INSERT INTO t(name) VALUES('Bob')\", NULL, NULL, &err);
// 查詢
sqlite3_exec(db, \"SELECT * FROM t\", printRow, NULL, &err);
sqlite3_close(db);
return 0;
}
適合一次取回全部結果集,記憶體配置由 SQLite 管理,需呼叫 sqlite3_free_table() 釋放。
int sqlite3_get_table(
sqlite3 *db, const char *sql,
char ***resultp, int *nRow, int *nCol, char **errmsg
);
char **result; int nRow, nCol;
sqlite3_get_table(db, \"SELECT * FROM t\", &result, &nRow, &nCol, &err);
for (int i = 0; i < nRow; ++i) {
for (int j = 0; j < nCol; ++j)
printf(\"%s: %s \", result[j], result[nCol + i*nCol + j]);
puts(\"\");
}
sqlite3_free_table(result);
SQLite 預設每條 sqlite3_exec 即一個自動提交事務。大量寫入時應手動控制:
sqlite3_exec(db, \"BEGIN TRANSACTION\", NULL, NULL, &err);
// 批次 INSERT/UPDATE/DELETE
sqlite3_exec(db, \"COMMIT TRANSACTION\", NULL, NULL, &err);
// 或
sqlite3_exec(db, \"ROLLBACK TRANSACTION\", NULL, NULL, &err);
將 10,000 筆 INSERT 包在單一事務中,速度可提升數十倍。
static,否則隱含 this 指標導致簽名不符errmsg 需在使用完後呼叫 sqlite3_free(errmsg) 釋放sqlite3* 需啟用序列化模式或自行加鎖掌握 SQLite C API 的開啟/關閉、sqlite3_exec 回調與 sqlite3_get_table 兩種查詢模式、事務批次處理,即可應付絕大多數嵌入式資料庫開發需求。