SQLite的C编程接口,可以简单总结为2个数据类型,8个接口1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23{
// 两个核心类型:
// - sqlite3: 句柄,代表连接
// - sqlite3_stmt: statement,可以简单理解为 sql 语句的抽象
sqlite3 *db = NULL; sqlite3_stmt *stmt = NULL;
// 八个核心 APIs:
// - sqlite3_open/sqlite3_close: 用于打开/关闭连接
// - sqlite3_prepare/sqlite3_finalize: 创建/销毁 statement
// - sqlite3_bind 系列: 为 statement 绑定参数
// - sqlite3_step: 执行 statement,对于 select 语句,可能要执行多次
// - sqlite3_reset: 将 statement 恢复到初始状态(譬如解除绑定的参数),以便重复使用
// - sqlite3_exec: sqlite3_prepare/sqlite3_step/sqlite3_finalize 的 wrapper
sqlite3_open("path/to/db", &db);
sqlite3_prepare(db, "select * from someTable where id = ?", -1, &stmt, NULL);
sqlite3_bind_int(stmt, 1, 42);
while (sqlite3_step(stmt) == SQLITE_ROW) {
// 使用 sqlite3_column 系列 API 提取数据
}
sqlite3_finalize(stmt); // 或者使用 `sqlite3_reset(stmt);`
sqlite3_exec(db, "drop table someTable", nil, NULL, NULL);
sqlite3_close(db);
}
数据库连接1
sqlite3 *db;
SQLite语句1
sqlite3_stmt *res;
开启一个数据库连接1
2
3
4
5
6
7
8int rc = sqlite3_open(":memory:", &db);
// :memory是内存数据库,或者使用磁盘db文件路径
if (rc != SQLITE_OK) {
fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
SQLite编译:生成字节码1
2
3
4
5
6
7rc = sqlite3_prepare_v2(db, "SELECT SQLITE_VERSION()", -1, &res, 0);
if (rc != SQLITE_OK) {
fprintf(stderr, "Failed to fetch data: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
5个参数(db, statement, 语句的最大字节长度, 语句句柄, 未使用的SQL语句部分)
执行SQL语句:1
2
3
4rc = sqlite3_step(res);
if (rc == SQLITE_ROW) {
printf("%s\n", sqlite3_column_text(res, 0));
}
对于SELECT语句的结果集,需要多次Step
销毁SQLite语句1
sqlite3_finalize(res);
关闭数据库连接:1
sqlite3_close(db);
另一个执行命令:1
2
3
4
5
6
7
8
9char *err_msg = 0;
rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
if (rc != SQLITE_OK ) {
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return 1;
}
对于非SELECT语句可以使用。
在SELECT中的使用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32int main(void) {
// ...
char *sql = "SELECT * FROM Cars";
rc = sqlite3_exec(db, sql, callback, 0, &err_msg);
if (rc != SQLITE_OK ) {
fprintf(stderr, "Failed to select data\n");
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return 1;
}
sqlite3_close(db);
// ...
}
int callback(void *NotUsed, int argc, char **argv,
char **azColName) {
NotUsed = 0;
for (int i = 0; i < argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
带参数查询://绑定1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20char *sql = "SELECT Id, Name FROM Cars WHERE Id = ?";
rc = sqlite3_prepare_v2(db, sql, -1, &res, 0);
if (rc == SQLITE_OK) {
sqlite3_bind_int(res, 1, 3);
} else {
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
}
int step = sqlite3_step(res);
if (step == SQLITE_ROW) {
printf("%s: ", sqlite3_column_text(res, 0));
printf("%s\n", sqlite3_column_text(res, 1));
}
参数命名占位:是个方便的绑定值的方式
1 | char *sql = "SELECT Id, Name FROM Cars WHERE Id = @id"; |
Named placeholders are prefixed with the colon (:) character or the at-sign (@) character.
二进制数据绑定
1 | sqlite3_bind_blob(pStmt, 1, data, size, SQLITE_STATIC); |
sqlite3默认运行在autocommit模式下(当当前连接关联的所有操作都已完成)
In autocommit mode, all changes to the database are committed as soon as all operations associated with the current database connection complete. Autocommit mode is disabled by a BEGIN statement and re-enabled by a COMMIT or ROLLBACK.
Comments