SQLite3:在C ++中插入带有NULL字符的BLOB

时间:2009-01-01 11:35:40

标签: sqlite null escaping blob

我正在开发使用自定义设计插件的C ++ API 使用API​​和特定SQL与不同的数据库引擎进行交互 语法。

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

合作
//...
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吗?

肯定有人必须面对同样的情况。我用Google搜索并找到了一些答案,但是使用其他编程语言(Python)。

提前感谢您的反馈。

3 个答案:

答案 0 :(得分:9)

再次感谢大家的反馈。这次我在报告如何借助此处提供的指示解决问题。希望这将有助于其他人。

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

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

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

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

void* blobvalue[4];
int blobsize[4];
char *tail, *sql="INSERT INTO table VALUES(?,?,?,?)";
sqlite3_stmt *stmt=0;
sqlite3 *db;
/* ... */
db=sqlite3_open("sqlite.db");
sqlite3_prepare_v2(db, 
                   sql, strlen(sql)+1, 
                   &stmt, &tail);
for(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及更高版本)。

答案 1 :(得分:8)

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

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

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

答案 2 :(得分:1)

您希望预编译语句sqlite_prepare_v2(),然后使用sqlite3_bind_blob()绑定blob。请注意,您绑定的语句将是 INSERT INTO表VALUES(?)