我在C ++中有以下代码来删除不在矢量ID中的所有ID。打印应该删除的ID,但由于ID绑定,DELETE似乎失败了。 (当我从语句中删除ID并仅绑定引用时,它运行良好)。
这就是数据库的创建方式:
CREATE TABLE IF NOT EXISTS Files (
ID LONGTEXT DEFAULT NULL,
Reference LONGTEXT NOT NULL,
FilePath LONGTEXT PRIMARY KEY NOT NULL,
ProcessedOn LONGTEXT NOT NULL)
删除正确ID的代码:
rc = sqlite3_prepare_v2(db, "SELECT ID FROM Files WHERE Reference=? AND ID IS NOT NULL", -1, &stmt, 0);
sqlite3_bind_text(stmt, 1, Settings["Reference"].c_str(), Settings["Reference"].length(), 0);
CheckDBError(rc);
rc = sqlite3_step(stmt);
sqlite3_stmt* stmt2;
int rc2 = sqlite3_prepare_v2(db, "DELETE FROM Files WHERE ID=? AND Reference=?", -1, &stmt2, 0);
CheckDBError(rc2);
while(rc == SQLITE_ROW) {
string IDToCheck = (const char*)sqlite3_column_text(stmt, 0);
cout << "Checking: " << IDToCheck << endl;
if (find(IDs.begin(), IDs.end(), IDToCheck) == IDs.end()) {
cout << "Delete " << IDToCheck << endl;
//SHOWS ME THE CORRECT ID's BUT THE DELETE IS NOT WORKING. THE
//STATEMENT IS EXECUTED PROPERLY WHEN I ONLY USE IT WITH BOUND
//REFERENCE, SO BINDING the IDToCheck GOES WRONG?
sqlite3_bind_text(stmt2, 1, IDToCheck.c_str(), IDToCheck.length(), 0);
sqlite3_bind_text(stmt2, 1, Settings["Reference"].c_str(), Settings["Reference"].length(), 0);
rc2 = sqlite3_step(stmt2);
}
rc = sqlite3_step(stmt);
}
sqlite3_finalize(stmt);
sqlite3_finalize(stmt2);
答案 0 :(得分:1)
sqlite3_bind_text() documentation说:
BLOB和字符串绑定接口的第五个参数是一个析构函数,用于在SQLite完成后处理BLOB或字符串。即使对绑定API的调用失败,也会调用析构函数来处置BLOB或字符串。如果第五个参数是特殊值SQLITE_STATIC,那么SQLite假定信息在静态的非托管空间中,并且不需要释放。如果第五个参数的值为SQLITE_TRANSIENT,则SQLite会在sqlite3_bind _ *()例程返回之前立即创建自己的数据私有副本。
您没有使用显式析构函数释放的动态缓冲区,因此您无法使用函数指针。
c_str()
返回的缓冲区不是非托管缓冲区,因此您无法使用SQLITE_STATIC
。
所以你必须使用SQLITE_TRANSIENT
。
此外,您必须检查错误(请检查rc2
,然后致电sqlite3_errmsg()。
此外,您需要reset语句才能再次执行它。