悠悠楠杉
C语言操作SQLite数据库完全指南:从入门到实战
本文详细介绍如何在C语言中使用SQLite数据库,包含环境配置、API详解、事务处理等实战技巧,提供完整代码示例和最佳实践建议。
SQLite作为轻量级关系型数据库,因其零配置、无服务端的特点,成为C语言项目嵌入式数据库的首选。本文将带你全面掌握SQLite3的C语言接口使用。
一、环境准备
首先确保系统已安装SQLite3开发库:
bash
Ubuntu/Debian
sudo apt-get install sqlite3 libsqlite3-dev
CentOS/RHEL
sudo yum install sqlite sqlite-devel
编译时需要链接SQLite3库:
bash
gcc program.c -lsqlite3 -o program
二、核心API详解
1. 数据库连接/断开
c
include <sqlite3.h>
int main() {
sqlite3 *db; // 数据库句柄
int rc = sqlite3_open("test.db", &db);
if(rc != SQLITE_OK) {
fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));
return 1;
}
// ...数据库操作...
sqlite3_close(db);
return 0;
}
注意:现代SQLite推荐使用sqlite3_open_v2()
,支持更多打开模式:
c
sqlite3_open_v2("file:test.db?mode=rwc", &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
2. 执行SQL语句
简易查询(无返回结果)
c
char *err_msg = NULL;
rc = sqlite3_exec(db, "CREATE TABLE users(id INT, name TEXT);",
NULL, NULL, &err_msg);
if(rc != SQLITEOK) {
fprintf(stderr, "SQL错误: %s\n", errmsg);
sqlite3free(errmsg);
}
带回调的查询
c
static int callback(void *data, int argc, char **argv, char **colName) {
for(int i=0; i<argc; i++) {
printf("%s = %s\n", colName[i], argv[i] ? argv[i] : "NULL");
}
return 0;
}
sqlite3exec(db, "SELECT * FROM users;", callback, NULL, &errmsg);
3. 预处理语句(推荐方式)
c
sqlite3_stmt *stmt;
const char *sql = "INSERT INTO users VALUES(?, ?);";
rc = sqlite3preparev2(db, sql, -1, &stmt, NULL);
if(rc != SQLITE_OK) {
// 错误处理
}
// 绑定参数(索引从1开始)
sqlite3bindint(stmt, 1, 1001);
sqlite3bindtext(stmt, 2, "张三", -1, SQLITE_STATIC);
rc = sqlite3step(stmt);
if(rc != SQLITEDONE) {
// 执行失败处理
}
sqlite3_finalize(stmt); // 必须释放资源
三、高级特性实践
1. 事务处理
c
sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, NULL);
// 执行多条SQL
sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
2. 错误处理规范
c
define DB_CHECK(db, stmt) \
if(rc != SQLITE_OK) { \
fprintf(stderr, "%s\n", sqlite3_errmsg(db)); \
if(stmt) sqlite3_finalize(stmt); \
sqlite3_close(db); \
return rc; \
}
// 使用示例
rc = sqlite3preparev2(db, sql, -1, &stmt, NULL);
DB_CHECK(db, stmt);
3. 二进制数据存储
c
// 写入BLOB
const void data = / 二进制数据 /;
int len = / 数据长度 */;
sqlite3_bind_blob(stmt, 1, data, len, SQLITE_STATIC);
// 读取BLOB
const void *blob = sqlite3_column_blob(stmt, 0);
int blob_size = sqlite3_column_bytes(stmt, 0);
四、最佳实践建议
- 连接管理:长时间空闲的连接应当关闭重建
- 预处理复用:频繁执行的SQL应当缓存stmt对象
- 错误日志:记录完整的错误上下文信息
- 内存管理:
- 使用
SQLITE_STATIC
避免不必要的数据拷贝 - 及时调用
sqlite3_free()
释放资源
- 使用
完整项目示例:c
// 创建用户表并插入示例数据
void initdb(sqlite3 *db) {
sqlite3exec(db, "DROP TABLE IF EXISTS users;", NULL, NULL, NULL);
sqlite3_exec(db, "CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT NOT NULL);",
NULL, NULL, NULL);
sqlite3_stmt *stmt;
sqlite3_prepare_v2(db, "INSERT INTO users(name) VALUES(?);", -1, &stmt, NULL);
const char *names[] = {"王小明", "李华", "张小红"};
for(int i=0; i<3; i++) {
sqlite3_bind_text(stmt, 1, names[i], -1, SQLITE_STATIC);
sqlite3_step(stmt);
sqlite3_reset(stmt);
}
sqlite3_finalize(stmt);
}