8

我正在开发一个 C++ API,它使用定制设计的插件来使用它们的 API 和特定的 SQL 语法与不同的数据库引擎进行交互。

目前,我正在尝试找到一种插入 BLOB 的方法,但由于NULL是 C/C++ 中的终止字符,因此在构造INSERT INTO查询字符串时 BLOB 会被截断。到目前为止,我已经与

//...
char* sql;
void* blob;
int len;
//...
blob = some_blob_already_in_memory;
len = length_of_blob_already_known;
sql = sqlite3_malloc(2*len+1);
sql = sqlite3_mprintf("INSERT INTO table VALUES (%Q)", (char*)blob);
//...

我希望,如果可以在 SQLite3 交互式控制台中执行此操作,那么应该可以使用正确转义的NULL字符构造查询字符串。也许有一种方法可以使用 SQLite SQL 语法也支持的标准 SQL 来做到这一点?

肯定有人以前遇到过同样的情况。我用谷歌搜索并找到了一些答案,但使用的是其他编程语言(Python)。

预先感谢您的反馈。

4

3 回答 3

10

再次感谢大家的反馈。这一次,我报告了我是如何借助此处提供的指示解决问题的。希望这将在未来对其他人有所帮助。

正如前三张海报所建议的,我确实使用了准备好的语句——另外因为我也对获取列的数据类型感兴趣,而简单的sqlite3_get_table()不会这样做。

准备好以下常量字符串形式的 SQL 语句后:

INSERT INTO table VALUES(?,?,?,?);

它仍然是相应值的绑定。这是通过发出sqlite3_bind_blob()与列一样多的调用来完成的。(我还求助于sqlite3_bind_text()其他“简单”数据类型,因为我正在处理的 API 可以将整数/双精度/等转换为字符串)。所以:

#include <stdio.h>
#include <string.h>
#include <sqlite3.h>
/* ... */
void* blobvalue[4] = { NULL, NULL, NULL, NULL };
int blobsize[4] = { 0, 0, 0, 0 };
const char* tail = NULL;
const char* sql = "INSERT INTO tabl VALUES(?,?,?,?)";
sqlite3_stmt* stmt = NULL;
sqlite3* db = NULL;
/* ... */
sqlite3_open("sqlite.db", &db);
sqlite3_prepare_v2(db,
                   sql, strlen(sql) + 1,
                   &stmt, &tail);
for(unsigned int i = 0; i < 4; i++) {
    sqlite3_bind_blob(stmt, 
                      i + 1, blobvalue[i], blobsize[i], 
                      SQLITE_TRANSIENT);
}
if(sqlite3_step(stmt) != SQLITE_DONE) {
    printf("Error message: %s\n", sqlite3_errmsg(db));
}
sqlite3_finalize(stmt);
sqlite3_close(db);

另请注意,某些函数(sqlite3_open_v2(), sqlite3_prepare_v2())出现在更高版本的 SQLite 上(我想是 3.5.x 及更高版本)。

可以使用(例如)创建tabl文件中的 SQLite 表sqlite.db

CREATE TABLE tabl(a TEXT PRIMARY KEY, b TEXT, c TEXT, d TEXT);
于 2009-01-02T22:08:41.977 回答
9

您将希望将此函数与准备好的语句一起使用。

int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));

在 C/C++ 中,处理字符串中的 NULL 的标准方法是存储字符串的开头和长度,或者存储指向字符串开头的指针和指向字符串结尾的指针。

于 2009-01-02T02:38:13.817 回答
1

您要预编译语句sqlite_prepare_v2(),然后在 using 中绑定 blob sqlite3_bind_blob()。请注意,您绑定的语句将是INSERT INTO table VALUES (?)

于 2009-01-01T12:57:58.993 回答