1

我正在编写一个函数来准备一个 sql 查询并针对一个 sqlite 数据库执行它。我正在使用查询将值插入到表中,查询看起来像这样

   "insert into files values (?, ?, ?, ?, ?, 0)";

插入了一行,但文本字段的所有值都是空的,除了最后一个字段为 0。前 5 个字段的类型为 TEXT

    // If I hard code a value for value.data() then the row is inserted correctly with my hardcoded data, the exact line is below
    status = sqlite3_bind_text(ppStmt, index, /* if I hardcode it works*/ value.data(), -1, SQLITE_STATIC);

完整的功能如下所示。列表是由调用者在堆栈上创建的,我不确定为什么它没有用我的字符串 args 替换问号,但硬编码的可以工作.. 没有返回错误代码

    //db is already open before I call this
void MediaCache::prepareAndExecuteQuery(string query, list<string> args)
{

    sqlite3_stmt *ppStmt = 0;
    const char **pzTail = 0;
    int status = 0;

    if( sqlite3_prepare_v2(db, query.data(), query.length(), &ppStmt, pzTail) != SQLITE_OK )
    {
        string error = sqlite3_errmsg(db);
        //throw an exception
    } 

    if(ppStmt)
    {

        list<string>::iterator current = args.begin();
        int index = 1;

        for(current = args.begin() ; current != args.end(); current++)
        {
            string value = *current;            
            status = sqlite3_bind_text(ppStmt, index, value.data(), -1, SQLITE_STATIC);

            if(status != SQLITE_OK)
            {
                //log error;
            }

            index++;
        }   

        status = sqlite3_step(ppStmt);
        status = sqlite3_finalize(ppStmt);
        //sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
    }
    else
    {
        //ppStmt is null
        //throw an exception
    }

}
4

1 回答 1

2

我怀疑问题出在这里:

string value = *current;            
status = sqlite3_bind_text(ppStmt, index, value.data(), -1, SQLITE_STATIC);

在这种情况下value,在执行语句之前就超出了范围。所以给出的指针sqlite3_bind_text不再有效。要“解决”这个问题,您可以使用 SQLITE_TRANSIENT,它会强制库在返回之前制作自己的数据副本。

此外,如果您不使用 C++11,我不相信string::data()一定会以 NULL 终止,在这种情况下 -1 参数可能不正确。也许应该是value.length()

于 2013-01-23T19:18:25.953 回答