1

我正在尝试减少对象中重复的 sqlite 代码。为此,我想要一种具有 sqlite 交互并且只返回 sqlite3_stmt 的方法。我的问题是 sqlite3_stmt 指针始终为空。我的问题是,我做错了什么还是不能用 sqlite 完成?

用法:

SqliteIO sqldb;
string GET_CONFIG = "select* from config; ";
sqlite3_stmt *statement;
assert(sqldb.sqlForResults(GET_CONFIG, statement));
assert(statement != NULL); //this fails

方法:

bool SqliteIO::sqlForResults(string pSql, sqlite3_stmt *statement ){
bool lbRetVal=false;

if(mDB == NULL){
    cerr << "No database to query";
    Logger::error("SqlliteIO::getAllScheuled() null database handle");
} else {
    sqlite3_busy_timeout(mDB, 2000);
    if(sqlite3_prepare_v2(mDB, pSql.c_str(), -1, &statement, 0) == SQLITE_OK) {
        lbRetVal = true;
    }
    string error = sqlite3_errmsg(mDB);
    if(error != "not an error"){
        cerr << pSql << " " << error << endl;
        Logger::error("SqlliteIO::sqlForResults() "+ error + " " +pSql  );
    }
}
return lbRetVal;
4

2 回答 2

1
sqlite3_stmt *statement; // this never gets initialized
assert(sqldb.sqlForResults(GET_CONFIG, statement));
assert(statement != NULL); //this fails

该代码块中的语句变量永远不会被初始化(您将它的副本传递给 sqlForResults())。

坦率地说,你很幸运断言失败,因为语句可能有任何垃圾值(我猜变量在你的编译器的调试模式下是零初始化的)

于 2012-07-18T17:05:08.163 回答
0

The statement parameter of SqliteIO::sqlForResults() needs to have the type sqlite3_stmt**, not sqlite3_stmt*. So the call site would now look like:

SqliteIO sqldb;
string GET_CONFIG = "select* from config; ";
sqlite3_stmt *statement = NULL;
assert(sqldb.sqlForResults(GET_CONFIG, &statement));

Without the reference/address-of operator & before statement (like in the original question), you would be passing the value of statement to sqlForResults, which was NULL or 0 in this case. The relevant changes in sqlForResults are:

bool SqliteIO::sqlForResults(string pSql, sqlite3_stmt **statement ){
bool lbRetVal=false;

if(mDB == NULL){
    // ...
} else {
    // ...
    if(sqlite3_prepare_v2(mDB, pSql.c_str(), -1, statement, 0) == SQLITE_OK) {
        // ...
    }
    // ...
}
return lbRetVal;

The parameter list now accepts a sqlite_stmt** arg, and we pass that directly to sqlite3_prepare_v2. In the original question, sqlForResults passed &statement to sqlite3_prepare_v2 - which is the address of the statement parameter for this SqliteIO::sqlForResults method call - which isn't what you want.

I know this is an old question, but I hope this helps.

EDIT: for clarity and to elude some more code from sqlForResults

于 2013-04-16T00:25:43.343 回答