Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ sqlite查询未准备好插入的行,但为空值_C++_Sqlite - Fatal编程技术网

C++ sqlite查询未准备好插入的行,但为空值

C++ sqlite查询未准备好插入的行,但为空值,c++,sqlite,C++,Sqlite,我正在编写一个函数来准备sql查询并对sqlite db执行它。我使用查询将值插入到表中,查询如下所示 "insert into files values (?, ?, ?, ?, ?, 0)"; 插入一行,但文本字段的所有值均为空,最后一个字段为0。前5个字段为文本类型 // If I hard code a value for value.data() then the row is inserted correctly with my hardcoded data, the

我正在编写一个函数来准备sql查询并对sqlite db执行它。我使用查询将值插入到表中,查询如下所示

   "insert into files values (?, ?, ?, ?, ?, 0)";
插入一行,但文本字段的所有值均为空,最后一个字段为0。前5个字段为文本类型

    // 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);
完整的函数如下所示。该列表是由calller在堆栈上创建的,我不知道为什么它不能用我的字符串参数替换问号,尽管硬编码的参数可以工作。。没有返回错误代码

    //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
    }

}
//在我调用此函数之前,db已打开
void MediaCache::prepareAndExecuteQuery(字符串查询,列表参数)
{
sqlite3_stmt*ppStmt=0;
常量字符**pzTail=0;
int status=0;
if(sqlite3\u prepare\u v2(db,query.data(),query.length(),&ppStmt,pzTail)!=SQLITE\u确定)
{
字符串错误=sqlite3\u errmsg(db);
//抛出异常
} 
如果(ppStmt)
{
list::iterator current=args.begin();
int指数=1;
对于(当前=args.begin();当前!=args.end();当前++)
{
字符串值=*当前值;
status=sqlite3\u bind\u text(ppStmt,index,value.data(),-1,SQLITE\u STATIC);
如果(状态!=SQLITE\u正常)
{
//日志错误;
}
索引++;
}   
状态=sqlite3_步骤(ppStmt);
状态=sqlite3_最终确定(ppStmt);
//sqlite3_exec(db,“COMMIT”,NULL,NULL,NULL);
}
其他的
{
//ppStmt为空
//抛出异常
}
}

我怀疑问题出在这里:

string value = *current;            
status = sqlite3_bind_text(ppStmt, index, value.data(), -1, SQLITE_STATIC);
在这种情况下,
value
在语句执行之前超出范围。因此,指定给
sqlite3\u bind\u text
的指针不再有效。为了“修复”这个问题,您可以使用SQLITE_TRANSIENT,这将迫使库在返回之前创建自己的数据副本


另外,如果您不使用C++11,我不认为
string::data()
保证以NULL结尾,在这种情况下,-1参数可能不正确。它可能应该是
value.length()

列0-4的数据类型是什么?类型是前5个字段的文本。我在前面的问题中已经回答了这个问题。查看如何绑定参数。您可以使用
std::stringstream
进行绑定。@m0skit0是的,我知道有答案,但它是C#答案,这是我关于C api的特定问题,它不起作用,我正在试图找出它不起作用的原因Mark,在这种情况下,您会使用引用或常量引用而不是副本吗?我同意我认为至少像
c_str()
这样的东西更适合字符串常量。@WhozCraig:我认为使用(*current).data()可以。只要字符串在执行之前没有改变,我相信这些指针是有效的。谢谢马克,使用SQLITE\u TRANSIENT或current->data()和SQLITE\u STATIC work,你的观察结果是正确的,值在执行之前超出范围。c_str()是否保证c字符串为空?我正在windows visual studio上开发,但最终它也将在上的xode上编译mac@Ahmed:是的,c_str应该保证一个空终止符。