【发布时间】:2014-10-12 04:42:49
【问题描述】:
所以我在 C 中与 SQLite 进行参数绑定时遇到了一些问题。我正在使用 sqlite3_bind_* 函数将 BLOB 和字符串插入数据库。然而,在插入之后,我用 SQLiteBrowser 检查了数据库,令我惊讶的是,这些类型都乱七八糟了!这是一些应该重现效果的示例代码。
-
这个块创建表。
const char *TABLE_NAME = "PASSWORD_ENTRY"; const char *USER_ID_COLUMN_NAME = "USER_ID"; const char *INDEX_COLUMN_NAME = "INDEX_VALUE"; const char *SERVICE_COLUMN_NAME = "SERVICE"; const char *SYM_ENC_KEY_COLUMN_NAME = "SYM_ENC_KEY"; const char *ASYM_ENC_KEY_COLUMN_NAME = "ASYM_ENC_KEY"; const char *TIMESTAMP_COLUMN_NAME = "TIMESTAMP"; /* CREATE TABLE IF NOT EXISTS TABLE_NAME ( USER_ID_COLUMN_NAME INTEGER, INDEX_COLUMN_NAME INTEGER, SERVICE_COLUMN_NAME TEXT, SYM_ENC_KEY_COLUMN_NAME BLOB, ASYM_ENC_KEY_COLUMN_NAME BLOB, TIME_STAMP_COLUMN_NAME BLOB, PRIMARY KEY (USER_ID_COLUMN_NAME, INDEX_COLUMN_NAME)); */ char *f = "CREATE TABLE IF NOT EXISTS %s (%s INTEGER, %s INTEGER, %s TEXT, %s BLOB, %s BLOB, %s BLOB, PRIMARY KEY (%s, %s));"; char *s = malloc(snprintf(NULL, 0, f, TABLE_NAME, USER_ID_COLUMN_NAME, INDEX_COLUMN_NAME, SERVICE_COLUMN_NAME, SYM_ENC_KEY_COLUMN_NAME, ASYM_ENC_KEY_COLUMN_NAME, TIMESTAMP_COLUMN_NAME, USER_ID_COLUMN_NAME, INDEX_COLUMN_NAME) + 1); sprintf(s, f, TABLE_NAME, USER_ID_COLUMN_NAME, INDEX_COLUMN_NAME, SERVICE_COLUMN_NAME, SYM_ENC_KEY_COLUMN_NAME, ASYM_ENC_KEY_COLUMN_NAME, TIMESTAMP_COLUMN_NAME, USER_ID_COLUMN_NAME, INDEX_COLUMN_NAME); const char *DB_NAME = "passwordmanager.db"; sqlite3* db; int r = 0; // Get the database r = sqlite3_open(DB_NAME, &db); if (r) { printf("Error opening database: %s\n", sqlite3_errmsg(db)); return NULL; } printf("Database opened.\n"); r = sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL); if (r) { printf("Error preparing create table statement: %s\n", sqlite3_errmsg(db)); return 1; } r = sqlite3_step(stmt); if (r != 101 && r) { printf("Error executing create table statement: %s\n", sqlite3_errmsg(db)); return 1; } printf("Password entry table ready.\n"); sqlite3_finalize(stmt); -
现在已经完成了,我会给你一个示例插入。
sqlite3_stmt *stmt2; long userId = 50l; short index = 2; long timestamp = 100l; char *service = "stackoverflow.com"; const int SYM_ENC_KEY_LEN = 10; const int ASYM_ENC_KEY_LEN = 11; char *symEncKey = "symEncKey"; char *asymEncKey = "asymEncKey"; char *f = "INSERT INTO PASSWORD_ENTRY (USER_ID, INDEX_VALUE, SERVICE, TIMESTAMP, SYM_ENC_KEY, ASYM_ENC_KEY) VALUES (?, ?, ?, ?, ?, ?);"; printf("SQL ready.\n"); r = sqlite3_prepare_v2(db, f, strlen(f), &stmt2, NULL); if (r != 0) { printf("Error preparing addition statement: %s\n", sqlite3_errmsg(db)); sqlite3_finalize(stmt2); sqlite3_close(db); return; } printf("Prepared the addition statement, binding...\n"); sqlite3_bind_int64(stmt2, 1, (sqlite3_int64) userId); sqlite3_bind_int(stmt2, 2, (int) index); sqlite3_bind_text(stmt2, 3, service, strlen(service) + 1, 0); sqlite3_bind_int64(stmt2, 4, (sqlite_int64) timestamp); sqlite3_bind_blob(stmt2, 5, (void *) symEncKey, SYM_ENC_KEY_LEN, 0); sqlite3_bind_blob(stmt2, 6, (void *) asymEncKey, ASYM_ENC_KEY_LEN, 0); // Execute the statement r = sqlite3_step(stmt2); if (r != 101) { printf("Error executing addition statement: %s\n", sqlite3_errmsg(db)); sqlite3_finalize(stmt2); sqlite3_close(db); return; } printf("Executed the addition statement.\n"); sqlite3_finalize(stmt2); sqlite3_close(db);
现在,如果您想使用 SQLiteBrowser 或您可能拥有的任何类似工具查看数据库,前提是您的运气和我一样,您会看到 SERVICE 列包含一个 BLOB,而 SYM_ENC_KEY 列包含一个字符串,不管我使用了相反的 sqlite3_bind_* 函数。有谁知道这是怎么发生的?如果您需要更多信息,请询问。我是新海报。
【问题讨论】:
-
这段代码无法编译。