当绑定发生在另一个函数中时,Sqlite _only_ 找不到行

Sqlite doesn't find row _only_ when binding takes places in another function

所以我自己写了一个包装函数来为我做一个准备好的声明:

sqlite3_stmt* Gladiateur::run_query_unfinalized(string query, vector<string> inputs){

    sqlite3_stmt *statement;

    // Prepare SQL
    sqlite3_prepare_v2(db, query.c_str(), -1, &statement, NULL);

    // Bind parameter
    sqlite3_bind_text(statement, 1, inputs[0].c_str(), -1, NULL);

    return statement;

}

通常它会通过输入向量并绑定所有字符串,但我简化了代码以找出错误所在。

我还有一个函数set_list(也简化了):

int Gladiateur::set_list (string list_name) {

    vector<string> bind = {list_name};
    sqlite3_stmt *statement = this->run_query_unfinalized("SELECT id FROM lists WHERE name = ? LIMIT 1", bind);

    printf("code %d\n", sqlite3_step(statement));

    sqlite3_finalize(statement);

    return 1;

}

我调用了 set_list,我得到了 "code 101",这只是意味着没有 SQL 错误,但没有检索到任何行。不过,我知道存在匹配的行。

奇怪的部分来了:我移动了线

sqlite3_bind_text(statement, 1, inputs[0].c_str(), -1, NULL);

进入 set_list 函数,就在 printf 上面,并写 bind[0] 而不是 inputs[0]。它有效!我得到 "code 100",找到了该行,当我检查时它也给了我正确的 ID。

但我想在 run_query_unfinalized 中进行所有绑定...我真的很困惑为什么它不起作用。也许我不能像那样传递 statement 变量?

Gladiateur::run_query_unfinalized(string query, vector<string> inputs)

vector<string> inputs是一个副本,当函数returns时不复存在。

也许您应该将其更改为:

Gladiateur::run_query_unfinalized(const string& query, const vector<string>& inputs)

有了参考,c_str应该能活下来做你想做的事。

sqlite3_bind_text函数的最后一个参数不能为NULL:

The fifth argument to the BLOB and string binding interfaces is a destructor used to dispose of the BLOB or string after SQLite has finished with it. The destructor is called to dispose of the BLOB or string even if the call to bind API fails. If the fifth argument is the special value SQLITE_STATIC, then SQLite assumes that the information is in static, unmanaged space and does not need to be freed. If the fifth argument has the value SQLITE_TRANSIENT, then SQLite makes its own private copy of the data immediately, before the sqlite3_bind_*() routine returns.

在这种情况下,您需要SQLITE_TRANSIENT