SQLite的C编程接口

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
8
int 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
7
rc = 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
4
rc = 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
9
char *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
32
int 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
20
char *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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
char *sql = "SELECT Id, Name FROM Cars WHERE Id = @id";
       
    rc = sqlite3_prepare_v2(db, sql, -1, &res, 0);
   
    if (rc == SQLITE_OK) {
       
        int idx = sqlite3_bind_parameter_index(res, "@id");
        int value = 4;
        sqlite3_bind_int(res, idx, value);
       
    } else {
       
        fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
    }
   
    int step = sqlite3_step(res);

Named placeholders are prefixed with the colon (:) character or the at-sign (@) character.

二进制数据绑定

1
2
3
4
5
sqlite3_bind_blob(pStmt, 1, data, size, SQLITE_STATIC);   
rc = sqlite3_step(pStmt);
if (rc != SQLITE_DONE) {       
        printf("execution failed: %s", sqlite3_errmsg(db));
}

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