libsqlite3-dev 介紹(Linux 下的 SQLite3 C/C++ 開發包)
libsqlite3-dev
是一個開發包,在 Linux 環境下為使用 SQLite3 C API 進行開發的 C/C++ 程序員提供頭文件(如 sqlite3.h
)和靜態庫/動態庫的鏈接信息(如 libsqlite3.so
)。
它是 SQLite3 數據庫的開發接口版本,不提供命令行工具,而是用于編譯和構建程序時使用。
libsqlite3-dev 包含的內容:
類型 | 路徑 | 描述 |
---|---|---|
頭文件 | /usr/include/sqlite3.h | 主頭文件,聲明所有 SQLite3 C API 函數,如 sqlite3_open 、sqlite3_exec 、sqlite3_close 等 |
/usr/include/sqlite3ext.h | SQLite3 插件擴展接口(用于實現用戶自定義函數等) | |
動態庫 | /usr/lib/x86_64-linux-gnu/libsqlite3.so | 動態鏈接庫,編譯時鏈接使用,運行時自動加載 |
靜態庫 | /usr/lib/x86_64-linux-gnu/libsqlite3.a | 靜態鏈接庫(可選,靜態鏈接使用) |
頭文件路徑 | /usr/include/ | 所有頭文件通常放在此處,包含時使用 <sqlite3.h> |
libsqlite3-dev的安裝
sudo apt update
sudo apt install libsqlite3-dev
安裝成功后的簡單示例:
test_sqlite3.cpp
:
#include <sqlite3.h>
#include <iostream>int main() {sqlite3* db = nullptr;int rc = sqlite3_open("test.db", &db);if(rc != SQLITE_OK) {std::cerr << "打開數據庫失敗: " << sqlite3_errmsg(db) << std::endl;if (db) {sqlite3_close(db); // 即使打開失敗也可能需要關閉 db}return 1;}std::cout << "SQLite3 數據庫打開成功!" << std::endl;sqlite3_close(db);return 0;
}
編譯:
gcc test_sqlite3.c -o test_sqlite3 -lsqlite3
正常情況下運行后輸出:
SQLite3 數據庫打開成功!
<sqlite3.h>
介紹
<sqlite3.h>
是 SQLite3 的主頭文件,提供了完整的 SQLite3 C 接口函數集,你可以通過它來完成:
-
打開或創建數據庫文件(
sqlite3_open
) -
執行 SQL(
sqlite3_exec
) -
查詢數據(
sqlite3_prepare_v2
+sqlite3_step
+sqlite3_column_xxx
) -
錯誤處理(
sqlite3_errmsg
) -
事務管理(
BEGIN
,COMMIT
,ROLLBACK
) -
內存管理、自定義函數、BLOB 操作等高級特性
它是你在 Linux 下用 C/C++ 訪問 SQLite3 數據庫的入口。
<sqlite3
.h>中的結構體
常用結構體簡介
結構體名 | 類型 | 作用描述 | 使用場景舉例 |
---|---|---|---|
sqlite3 | 數據庫連接對象 | 表示與 SQLite 數據庫的連接,所有操作都依賴它 | sqlite3_open , sqlite3_close 用于打開和關閉數據庫 |
sqlite3_stmt | 預處理語句句柄 | 表示一條 SQL 語句的預編譯句柄(如 SELECT、INSERT、UPDATE) | sqlite3_prepare_v2 , sqlite3_step 用于執行預處理語句 |
sqlite3_value | 列值 | 表示 SQLite 查詢結果中的單一列數據的類型(可以是整數、文本、BLOB、NULL) | 使用 sqlite3_column_* 函數從查詢結果中提取數據 |
sqlite3_row | 行數據 | 表示數據庫查詢結果中的一行數據,存儲在一個 sqlite3_value 結構體中 | 遍歷查詢結果時,使用 sqlite3_column_* 獲取每一列 |
sqlite3_vfs | 虛擬文件系統 | 用于管理 SQLite 的文件 I/O 操作,定義 SQLite 如何讀寫數據文件 | 可用于自定義虛擬文件系統或定制文件 I/O |
sqlite3_context | 執行上下文 | 用于執行回調時保存狀態的結構體,通常在用戶定義的函數中使用 | 在自定義 SQLite 函數時使用,保存用戶的上下文數據 |
?sqlite3
sqlite3
結構體是 SQLite 數據庫的主要句柄,表示一個數據庫連接,管理數據庫的生命周期和執行查詢的操作。
typedef struct sqlite3 sqlite3;
示例:
sqlite3 *db;
int rc = sqlite3_open("test.db", &db);
if (rc) {fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
} else {printf("Opened database successfully\n");
}
sqlite3_value
sqlite3_value
結構體表示 SQLite 中的一個值(例如列值、函數參數)。它包含了該值的類型和實際的數據。
typedef struct sqlite3_value sqlite3_value;
示例:
sqlite3_value *value;
value = sqlite3_column_value(stmt, 0);
if (sqlite3_value_type(value) == SQLITE_INTEGER) {printf("Value is integer: %lld\n", sqlite3_value_int64(value));
}
sqlite3_row
sqlite3_row
結構體表示查詢結果中的一行數據。SQLite 使用它來存儲查詢返回的每一行的字段數據。
typedef struct sqlite3_row sqlite3_row;
示例:
sqlite3_row *row;
while ((row = sqlite3_fetch_row(stmt)) != NULL) {const char *name = sqlite3_column_text(row, 0);int age = sqlite3_column_int(row, 1);printf("Name: %s, Age: %d\n", name, age);
}
sqlite3_stmt
sqlite3_stmt
結構體表示一個預處理語句。它包含了 SQL 查詢的編譯結果,并提供了執行該查詢的接口。
typedef struct sqlite3_stmt sqlite3_stmt;
示例:
sqlite3_stmt *stmt;
const char *sql = "SELECT id, name FROM users WHERE age > ?";
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
<sqlite3.h>中常用的方法
1. 初始化與連接管理
sqlite3_open
用于打開一個 SQLite 數據庫連接(若數據庫文件不存在則嘗試創建),是使用 SQLite 的入口函數之一。
int sqlite3_open(const char *filename, sqlite3 **ppDb);
參數:
-
filename
:數據庫文件名。如果傳入":memory:"
,則創建一個內存數據庫;如果傳入""
,創建一個臨時數據庫。 -
ppDb
:傳入一個 sqlite3 指針的地址,成功后返回已打開的數據庫連接指針。
返回值:
-
成功:返回
SQLITE_OK
。 -
失敗:返回其他錯誤碼,例如
SQLITE_CANTOPEN
。錯誤信息可通過sqlite3_errmsg()
獲取。
?
sqlite3_open_v2
是 sqlite3_open
的增強版本,支持更多控制選項(如只讀、創建標志、自定義虛擬文件系統等)。
int sqlite3_open_v2(const char *filename,sqlite3 **ppDb,int flags,const char *zVfs
);
參數:
-
filename
:數據庫文件路徑,規則同sqlite3_open
。 -
ppDb
:傳出參數,返回數據庫連接句柄。 -
flags
:控制數據庫打開行為。常用值包括:-
SQLITE_OPEN_READONLY
:只讀模式打開。 -
SQLITE_OPEN_READWRITE
:可讀寫(數據庫必須存在)。 -
SQLITE_OPEN_CREATE
:如果不存在則創建數據庫。 -
可組合使用,如
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
。
-
-
zVfs
:VFS 模塊名稱,傳NULL
使用默認模塊。
返回值:
int sqlite3_close(sqlite3*);
-
成功:返回
SQLITE_OK
。 -
失敗:返回錯誤碼,例如
SQLITE_CANTOPEN
、SQLITE_NOTADB
等。
sqlite3_close
關閉一個已經打開的 SQLite 數據庫連接,并釋放相關資源。此函數要求數據庫中沒有未完成的語句句柄(sqlite3_stmt
)或未釋放的內存,否則關閉會失敗。
int sqlite3_close(sqlite3*);
參數:
-
sqlite3*
:由sqlite3_open
或sqlite3_open_v2
打開的數據庫連接句柄。
返回值:
-
成功:返回
SQLITE_OK
。 -
失敗:返回
SQLITE_BUSY
(表示還有未釋放的資源,如未 finalize 的語句)。
sqlite3_close_v2
與 sqlite3_close
類似,也是關閉數據庫連接。但它允許有未清理的語句存在,數據庫會被標記為“延遲關閉”,直到最后一個資源被釋放后自動關閉。
int sqlite3_close_v2(sqlite3*);
sqlite3_errmsg
返回最近一次 SQLite 操作失敗的錯誤信息(字符串形式),用于調試和日志記錄。
const char *sqlite3_errmsg(sqlite3*);
參數:
-
sqlite3*
:數據庫連接句柄。
返回值:
-
返回一個字符串,表示上一次出錯時的詳細錯誤信息。這個字符串是由 SQLite 管理的,不需要手動釋放。
注意事項:
-
如果是線程安全模式,不要跨線程使用該字符串。
-
錯誤信息只對上一次失敗的調用有效,之后任何成功調用都會覆蓋它。
sqlite3_errcode
返回最近一次數據庫操作的錯誤代碼(整數形式),用于程序內判斷錯誤類型。
int sqlite3_errcode(sqlite3*);
參數:
-
sqlite3*
:數據庫連接句柄。
返回值:
-
返回錯誤代碼,如:
-
SQLITE_OK
:無錯誤。 -
SQLITE_BUSY
:資源忙。 -
SQLITE_ERROR
:SQL 錯誤或數據庫缺陷。 -
SQLITE_IOERR
:磁盤 I/O 錯誤。 -
SQLITE_NOMEM
:內存不足。 -
等等,詳見官方文檔錯誤碼列表。
-
sqlite3_extended_errcode
返回更詳細的錯誤碼,錯誤信息比 sqlite3_errcode
更細致,例如區分不同類型的 SQLITE_IOERR_*
。
int sqlite3_extended_errcode(sqlite3*);
參數:
-
sqlite3*
:數據庫連接句柄。
返回值:
-
返回擴展錯誤代碼,例如:
-
SQLITE_IOERR_READ
-
SQLITE_IOERR_WRITE
-
SQLITE_CONSTRAINT_UNIQUE
等
-
示例:
#include <sqlite3.h>
#include <iostream>void open_with_sqlite3_open(const char* filename) {sqlite3* db = nullptr;std::cout << "[sqlite3_open] 嘗試打開數據庫: " << filename << "\n";int rc = sqlite3_open(filename, &db);if (rc != SQLITE_OK) {std::cerr << "打開失敗\n";std::cerr << " 錯誤碼: " << sqlite3_errcode(db) << "\n";std::cerr << " 擴展錯誤碼: " << sqlite3_extended_errcode(db) << "\n";std::cerr << " 錯誤信息: " << sqlite3_errmsg(db) << "\n";} else {std::cout << "打開成功\n";}if (db) {sqlite3_close(db);std::cout << "[sqlite3_close] 已關閉數據庫連接\n";}
}void open_with_sqlite3_open_v2(const char* filename) {sqlite3* db = nullptr;std::cout << "[sqlite3_open_v2] 嘗試以讀寫模式打開數據庫: " << filename << "\n";int rc = sqlite3_open_v2(filename,&db,SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,nullptr // 使用默認 VFS);if (rc != SQLITE_OK) {std::cerr << "打開失敗\n";std::cerr << " 錯誤碼: " << sqlite3_errcode(db) << "\n";std::cerr << " 擴展錯誤碼: " << sqlite3_extended_errcode(db) << "\n";std::cerr << " 錯誤信息: " << sqlite3_errmsg(db) << "\n";} else {std::cout << "打開成功\n";}if (db) {sqlite3_close_v2(db);std::cout << "[sqlite3_close_v2] 已關閉數據庫連接(異步可安全延后)\n";}
}int main() {std::cout << "===== 使用 sqlite3_open =====\n";open_with_sqlite3_open("example_open.db");std::cout << "\n===== 使用 sqlite3_open_v2 =====\n";open_with_sqlite3_open_v2("example_open_v2.db");return 0;
}
2. 執行 SQL(直接執行)
sqlite3_exec
sqlite3_exec()
是 SQLite 提供的一個簡化接口,用于直接執行一條或多條 SQL 語句。適合執行不需要處理結果集的語句,如 CREATE TABLE
、INSERT
、UPDATE
、DELETE
等。
在 sqlite3_exec()
的執行過程中,我們可以通過回調函數來處理查詢結果,sqlite3_exec()
直接返回所有結果并逐行傳遞給回調函數。
int sqlite3_exec(sqlite3 *db, // 數據庫連接句柄const char *sql, // SQL 語句int (*callback)(void*,int,char**,char**), // 回調函數(可為 NULL)void *arg, // 傳給回調函數的參數(可為 NULL)char **errmsg // 出錯信息(執行失敗時會分配內存)
);
參數:
-
db
:打開的數據庫連接句柄(由sqlite3_open()
獲得)。 -
sql
:要執行的一條或多條 SQL 語句,語句之間用分號分隔。 -
callback
:每當 SQL 查詢返回一行結果時調用的函數。如果沒有回調函數,可以傳NULL
。 -
arg
:傳遞給回調函數的上下文數據,可以是任何自定義的數據。可以傳NULL
。 -
errmsg
:如果非NULL
,執行失敗時將設置指向錯誤信息字符串的指針。調用者需要在完成后調用sqlite3_free()
釋放此內存。
返回值:
-
SQLITE_OK
:表示執行成功。 -
其他錯誤碼:執行失敗,具體錯誤信息可以通過
errmsg
獲得。
示例:
#include <sqlite3.h>
#include <iostream>int callback(void* NotUsed, int argc, char** argv, char** azColName) {for (int i = 0; i < argc; i++) {std::cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL") << "\n";}std::cout << "------\n";return 0;
}int main() {sqlite3* db = nullptr;char* errMsg = nullptr;// 打開數據庫if (sqlite3_open("test_exec.db", &db) != SQLITE_OK) {std::cerr << "無法打開數據庫: " << sqlite3_errmsg(db) << "\n";return 1;}// 創建表并插入數據const char* sql = "CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, name TEXT);""INSERT INTO users(name) VALUES('Alice');""INSERT INTO users(name) VALUES('Bob');""SELECT * FROM users;";if (sqlite3_exec(db, sql, callback, nullptr, &errMsg) != SQLITE_OK) {std::cerr << "SQL 執行錯誤: " << errMsg << "\n";sqlite3_free(errMsg); // 釋放錯誤信息}// 關閉數據庫sqlite3_close(db);return 0;
}
3. 預處理語句與結果集處理
SQLite 不像 MySQL 那樣返回一個“結果集對象(MYSQL_RES)”,它通過“預處理語句對象”sqlite3_stmt*
來遍歷每一行返回結果。以下是預處理語句和處理查詢結果時的主要函數。
sqlite3_prepare_v2
將 SQL 語句編譯成可執行的預處理語句。
int sqlite3_prepare_v2(sqlite3 *db, // 數據庫連接句柄const char *sql, // 要編譯的 SQL 語句int nByte, // SQL 語句的長度,如果是字符串以外的字符,可以傳 -1sqlite3_stmt **ppStmt, // 輸出的 sqlite3_stmt 句柄const char **pzTail // 指向 SQL 語句中未被解析的部分,通常可以為 NULL
);
參數:
-
db
:數據庫連接句柄。 -
sql
:待編譯的 SQL 語句。 -
nByte
:SQL 語句的長度,若是字符串,傳 -1。 -
ppStmt
:返回預處理語句的sqlite3_stmt
句柄。 -
pzTail
:指向 SQL 語句未解析部分的指針,通常可以為NULL
。
返回值:
-
SQLITE_OK
:表示成功。 -
其他錯誤碼:表示失敗。
sqlite3_bind_* 系列函數
sqlite3_bind_*
系列函數用于將動態的值綁定到 SQL 語句中的占位符參數,以便執行時能夠傳遞實際數據。
常用函數:
-
sqlite3_bind_int
:綁定整數參數。 -
sqlite3_bind_text
:綁定文本參數。 -
sqlite3_bind_double
:綁定浮動參數。 -
sqlite3_bind_blob
:綁定二進制數據。 -
sqlite3_bind_null
:綁定 NULL 值。
int sqlite3_bind_int(sqlite3_stmt *pStmt, int iParam, int value);
int sqlite3_bind_text(sqlite3_stmt *pStmt, int iParam, const char *value, int n, void (*destructor)(void*));
int sqlite3_bind_double(sqlite3_stmt *pStmt, int iParam, double value);
int sqlite3_bind_blob(sqlite3_stmt *pStmt, int iParam, const void *value, int n, void (*destructor)(void*));
int sqlite3_bind_null(sqlite3_stmt *pStmt, int iParam);
-
參數:
-
pStmt
:預處理語句句柄。 -
iParam
:參數的索引,從 1 開始。 -
value
:要綁定的值。 -
n
:值的字節數,適用于文本、二進制數據。 -
destructor
:用于清理value
的回調函數,通常用于TEXT
和BLOB
數據類型。
-
-
返回值:
-
SQLITE_OK
:表示成功。 -
其他錯誤碼:表示失敗。
-
sqlite3_clear_bindings
用于清除通過 sqlite3_bind_*
系列函數綁定到 SQL 語句中的所有參數值,但不會重置語句的編譯狀態(即不會清除結果或重置游標)。適用于想重用已準備好的 SQL 語句但重新綁定新參數的場景。
int sqlite3_clear_bindings(sqlite3_stmt *pStmt);
參數:
-
pStmt:已準備好的 SQL 語句對象(
sqlite3_prepare_v2
的輸出)。
返回值:
-
返回
SQLITE_OK
表示綁定清除成功。 -
傳入非法的
pStmt
時可能返回其他錯誤碼。
sqlite3_reset
用于重置一個已執行的預處理語句(sqlite3_stmt*
),將其狀態清空,以便再次綁定參數并重新執行。該函數不會清除綁定的參數值(除非配合 sqlite3_clear_bindings()
使用),而是將語句返回到 sqlite3_step()
執行前的初始狀態。
int sqlite3_reset(sqlite3_stmt *pStmt);
參數:
-
pStmt:類型為
sqlite3_stmt*
,表示需要被重置的預處理語句句柄。這個句柄通常是通過sqlite3_prepare_v2()
創建的。
返回值:
-
返回
SQLITE_OK
表示重置成功,語句已回到初始狀態,下一次可以重新綁定參數并執行。 -
如果返回的是非
SQLITE_OK
的其他錯誤碼,則是該語句上一次執行sqlite3_step()
時的返回碼,這通常可用于調試或進一步的錯誤處理。
sqlite3_step
執行預處理語句并處理每一行的結果。
int sqlite3_step(sqlite3_stmt *pStmt);
參數:
-
pStmt
:預處理語句句柄,由sqlite3_prepare_v2
返回。
返回值:
-
SQLITE_ROW
:有一行數據可返回。 -
SQLITE_DONE
:查詢完成,所有行已處理完。 -
其他錯誤碼:表示執行過程中出錯。
每次調用 sqlite3_step
,都會推進 sqlite3_stmt
句柄至下一行數據。每當 sqlite3_step
返回 SQLITE_ROW
時,表示當前行的查詢結果可以通過 sqlite3_column_*
系列函數獲取。
sqlite3_column_* 系列函數
從當前行的結果中提取列的數據。
常用函數:
-
sqlite3_column_text
:返回文本類型的列數據。 -
sqlite3_column_int
:返回整數類型的列數據。 -
sqlite3_column_double
:返回浮動類型的列數據。 -
sqlite3_column_blob
:返回二進制數據。 -
sqlite3_column_bytes
:返回列數據的字節數。
const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int col);
int sqlite3_column_int(sqlite3_stmt *pStmt, int col);
double sqlite3_column_double(sqlite3_stmt *pStmt, int col);
const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int col);
int sqlite3_column_bytes(sqlite3_stmt *pStmt, int col);
-
參數:
-
pStmt
:預處理語句句柄。 -
col
:列的索引,從 0 開始。
-
-
返回值:
-
對應的列數據,如文本、整數、浮動等。
-
sqlite3_finalize
釋放預處理語句占用的資源。
int sqlite3_finalize(sqlite3_stmt *pStmt);
-
參數:
-
pStmt
:預處理語句句柄。
-
-
返回值:
-
SQLITE_OK
:表示成功。 -
其他錯誤碼:表示失敗。
-
使用 sqlite3_finalize
清理 sqlite3_stmt
占用的資源。即使查詢執行成功,釋放預處理語句也是必要的步驟。
示例:
#include <sqlite3.h>
#include <iostream>int main() {sqlite3 *db;sqlite3_stmt *stmt;// 打開數據庫if (sqlite3_open("test.db", &db) != SQLITE_OK) {std::cerr << "無法打開數據庫: " << sqlite3_errmsg(db) << "\n";return 1;}// 編譯 SQL 語句const char *sql = "SELECT id, name FROM users WHERE age > ?";if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {std::cerr << "無法編譯 SQL: " << sqlite3_errmsg(db) << "\n";sqlite3_close(db);return 1;}// 第一次綁定參數并執行查詢sqlite3_bind_int(stmt, 1, 30); // 綁定 age > 30std::cout << "查詢 age > 30 的用戶:\n";while (sqlite3_step(stmt) == SQLITE_ROW) {int id = sqlite3_column_int(stmt, 0);const unsigned char *name = sqlite3_column_text(stmt, 1);std::cout << "ID: " << id << ", Name: " << name << std::endl;}// 清除綁定參數并重置語句sqlite3_clear_bindings(stmt); // 清除參數綁定sqlite3_reset(stmt); // 重置語句狀態,準備再次執行// 第二次綁定新參數并再次查詢sqlite3_bind_int(stmt, 1, 20); // 綁定 age > 20std::cout << "\n查詢 age > 20 的用戶:\n";while (sqlite3_step(stmt) == SQLITE_ROW) {int id = sqlite3_column_int(stmt, 0);const unsigned char *name = sqlite3_column_text(stmt, 1);std::cout << "ID: " << id << ", Name: " << name << std::endl;}// 清理資源sqlite3_finalize(stmt);sqlite3_close(db);return 0;
}
4.狀態信息獲取
sqlite3_db_filename
該函數用于獲取當前數據庫連接所關聯的數據庫文件名。這對于調試、日志記錄或者獲取數據庫文件路徑非常有用。
const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
參數:
-
db
:SQLite 數據庫連接句柄。 -
zDbName
:數據庫名稱。如果是主數據庫,使用"main"
;如果是附加數據庫,使用附加數據庫的名稱。
返回值:
-
返回指定數據庫(如主數據庫或附加數據庫)對應的文件名(路徑)。如果出錯,則返回
NULL
。
示例:
const char *filename = sqlite3_db_filename(db, "main");
if (filename) {std::cout << "主數據庫文件路徑: " << filename << "\n";
} else {std::cerr << "獲取文件名失敗\n";
}
sqlite3_db_status
該函數用于獲取有關數據庫的狀態信息,如內存使用情況、鎖狀態、緩存大小等。它為用戶提供了一個接口來監控數據庫的性能和資源使用。
int sqlite3_db_status(sqlite3 *db, // 數據庫連接句柄int op, // 狀態信息的類型(如內存使用,鎖狀態等)int *pCur, // 當前狀態值int *pHiwater, // 高水位值int reset // 是否重置狀態
);
參數:
-
db
:SQLite 數據庫連接句柄。 -
op
:要查詢的狀態類型。常見的狀態類型有:-
SQLITE_DBSTATUS_LOOKASIDE_HIT
:查看緩存命中的次數。 -
SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE
:查看緩存未命中的大小。 -
SQLITE_DBSTATUS_CACHE_USED
:查看緩存當前使用的字節數。 -
SQLITE_DBSTATUS_MEMORY_USED
:查看當前內存使用量。 -
還有其他類型的狀態查詢,詳細請參考 SQLite 官方文檔。
-
-
pCur
:返回當前的狀態值。 -
pHiwater
:返回該狀態的最高水位(例如最大內存使用量)。 -
reset
:如果設置為非零值,則會重置狀態統計數據(用于獲取從上次調用以來的變化)。
返回值:
-
返回
SQLITE_OK
表示成功。 -
其他錯誤碼表示失敗。
示例:
int currentUsage = 0;
int highWaterMark = 0;
int rc = sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, ¤tUsage, &highWaterMark, 0);
if (rc == SQLITE_OK) {std::cout << "當前緩存使用字節數: " << currentUsage << "\n";std::cout << "緩存的最高使用字節數: " << highWaterMark << "\n";
} else {std::cerr << "獲取數據庫狀態失敗\n";
}
5.事務控制
SQLite 的事務控制相對簡化了一些,不像 MySQL 那樣提供專門函數(mysql_autocommit、mysql_commit、mysql_rollback等)。SQLite 更注重簡潔性和輕量性,因此很多事務控制操作都可以通過 sqlite3_exec
來完成,基本上是通過執行 SQL 語句來管理事務的開始、提交和回滾。
?示例:
#include <sqlite3.h>
#include <iostream>void execute_transaction(sqlite3 *db) {char *errMsg = nullptr;// 開始事務const char *beginSQL = "BEGIN TRANSACTION;";if (sqlite3_exec(db, beginSQL, nullptr, nullptr, &errMsg) != SQLITE_OK) {std::cerr << "開始事務失敗: " << errMsg << "\n";sqlite3_free(errMsg);return;}// 執行插入操作const char *insertSQL = "INSERT INTO users(name) VALUES('Alice');";if (sqlite3_exec(db, insertSQL, nullptr, nullptr, &errMsg) != SQLITE_OK) {std::cerr << "插入數據失敗: " << errMsg << "\n";sqlite3_free(errMsg);// 回滾事務const char *rollbackSQL = "ROLLBACK;";sqlite3_exec(db, rollbackSQL, nullptr, nullptr, &errMsg);return;}// 提交事務const char *commitSQL = "COMMIT;";if (sqlite3_exec(db, commitSQL, nullptr, nullptr, &errMsg) != SQLITE_OK) {std::cerr << "提交事務失敗: " << errMsg << "\n";sqlite3_free(errMsg);return;}std::cout << "事務執行成功\n";
}int main() {sqlite3 *db = nullptr;if (sqlite3_open("test_transaction.db", &db) != SQLITE_OK) {std::cerr << "無法打開數據庫: " << sqlite3_errmsg(db) << "\n";return 1;}// 執行事務execute_transaction(db);// 關閉數據庫sqlite3_close(db);return 0;
}
sqlite3.h中的錯誤碼和狀態碼
錯誤碼 | 常量名稱 | 含義描述 |
---|---|---|
0 | SQLITE_OK | 操作成功 |
1 | SQLITE_ERROR | 通用錯誤 |
2 | SQLITE_INTERNAL | SQLite 內部邏輯錯誤 |
3 | SQLITE_PERM | 訪問權限被拒絕 |
4 | SQLITE_ABORT | 回調函數請求中止 |
5 | SQLITE_BUSY | 數據庫文件被鎖定 |
6 | SQLITE_LOCKED | 數據庫表被鎖定 |
7 | SQLITE_NOMEM | 內存分配失敗 |
8 | SQLITE_READONLY | 數據庫處于只讀模式,無法寫入 |
9 | SQLITE_INTERRUPT | 操作被 sqlite3_interrupt() 中斷 |
10 | SQLITE_IOERR | 磁盤 I/O 錯誤 |
11 | SQLITE_CORRUPT | 數據庫文件損壞 |
12 | SQLITE_NOTFOUND | 未找到指定的操作或對象 |
13 | SQLITE_FULL | 數據庫已滿,無法插入數據 |
14 | SQLITE_CANTOPEN | 無法打開數據庫文件 |
15 | SQLITE_PROTOCOL | 數據庫鎖協議錯誤 |
16 | SQLITE_EMPTY | 內部使用,僅供 SQLite 內部操作使用 |
17 | SQLITE_SCHEMA | 數據庫模式(schema)變化 |
18 | SQLITE_TOOBIG | 字符串或二進制數據超出大小限制 |
19 | SQLITE_CONSTRAINT | 由于約束沖突(如 UNIQUE 或 FOREIGN KEY)導致的中止 |
20 | SQLITE_MISMATCH | 數據類型不匹配 |
21 | SQLITE_MISUSE | 錯誤的庫調用,表示 SQLite 被錯誤地使用 |
22 | SQLITE_NOLFS | 使用了操作系統不支持的特性 |
23 | SQLITE_AUTH | 授權被拒絕 |
24 | SQLITE_FORMAT | 未使用,未定義的錯誤碼 |
25 | SQLITE_RANGE | sqlite3_bind 的參數超出范圍 |
26 | SQLITE_NOTADB | 嘗試打開一個非數據庫文件 |
27 | SQLITE_NOTICE | 通知信息,通過 sqlite3_log() 返回 |
28 | SQLITE_WARNING | 警告信息,通過 sqlite3_log() 返回 |
100 | SQLITE_ROW | sqlite3_step() 有一行數據可返回 |
101 | SQLITE_DONE | sqlite3_step() 執行完成,所有行已處理完 |