Linux下的c/c++开发之操作Sqlite3数据库
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() 执行完成,所有行已处理完 |