首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

SQLite C API 核心操作全解析:開啟、執行、回調與事務

     編輯:MySQL 資料庫相關知識

前言

SQLite 以 C 語言介面(API)為核心,所有高階語言的驅動程式皆建構於此。本文深入解析 sqlite3_open、sqlite3_exec、回調函數機制、sqlite3_get_table 非回調查詢,以及事務控制,並提供可直接編譯執行的完整範例碼。

核心資料結構:sqlite3*

所有資料庫操作圍繞 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;
}

執行 SQL:sqlite3_exec 與回調機制

函數原型

int sqlite3_exec(
    sqlite3 *db,
    const char *sql,
    int (*callback)(void*,int,char**,char**),
    void *arg,
    char **errmsg
);

參數詳解

參數說明
dbsqlite3_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:對應欄位名稱

完整 CRUD 範例

// 回調:列印每一列
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;
}

非回調查詢:sqlite3_get_table

適合一次取回全部結果集,記憶體配置由 SQLite 管理,需呼叫 sqlite3_free_table() 釋放。

函數原型

int sqlite3_get_table(
    sqlite3 *db, const char *sql,
    char ***resultp, int *nRow, int *nCol, char **errmsg
);

結果陣列佈局

  • 索引 0 ~ nCol-1:欄位名稱
  • 索引 nCol 之後:逐列資料,按行優先展平

範例

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 包在單一事務中,速度可提升數十倍。

常見坑點提醒

  • C++ 成員函數作回調時必須宣告 static,否則隱含 this 指標導致簽名不符
  • errmsg 需在使用完後呼叫 sqlite3_free(errmsg) 釋放
  • 多執行緒環境下,同一 sqlite3* 需啟用序列化模式或自行加鎖

結語

掌握 SQLite C API 的開啟/關閉、sqlite3_exec 回調與 sqlite3_get_table 兩種查詢模式、事務批次處理,即可應付絕大多數嵌入式資料庫開發需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved