0

私のC++ページには、準備ステートメントがあります

sqlite3_stmt *sqlstmt;

これは、intを介してデータが渡されたときにSQLITE_OKを返します

string query;
query = "select * from A;"
int rc = sqlite3_prepare_v2(db,query.c_str(),0,&stmt,0);
if (SQLITE_OK != rc ){ return; } 

働き。

次に、次の行を開始します。

int rc;
rc = sqlite3_step(sqlstmt);
//rc = 21 here.

SQLITE3ドキュメントからの例外。私の現在のバージョンは3.07.14.01だと思います。

http://www.sqlite.org/c3ref/step.html

SQLITE_MISUSEは、このルーチンが不適切に呼び出されたことを意味します。おそらく、すでにファイナライズされている準備済みステートメント、または以前にSQLITE_ERRORまたはSQLITE_DONEを返したステートメントで呼び出されました。または、同じデータベース接続が同時に2つ以上のスレッドによって使用されている場合もあります。

3.6.23.1までのSQLiteのすべてのバージョンでは、sqlite3_step()がSQLITE_ROW以外のものを返した後、sqlite3_step()を呼び出す前に、sqlite3_reset()を呼び出す必要がありました。sqlite3_reset()を使用してプリペアドステートメントをリセットしないと、sqlite3_step()からSQLITE_MISUSEが返されます。しかし、バージョン3.6.23.1以降、sqlite3_step()は、SQLITE_MISUSEを返すのではなく、この状況でsqlite3_reset()の呼び出しを自動的に開始しました。SQLITE_MISUSEエラーを受け取ったアプリケーションは定義上破損しているため、これは互換性の破損とは見なされません。SQLITE_OMIT_AUTORESETコンパイル時オプションを使用して、レガシー動作を復元できます。

実際のコード関数

vector cDataInterpretor :: getWorkingSet(int userID){vector t_val; ベクトルretVal; sqlite3 * db; int rc; rc = sqlite3_open(databasePath.c_str()、&db); if(rc!= SQLITE_OK){sqlite3_close(db); t_valを返します。} string query = "select * from insp_Assets;"; char * errorMessage;

sqlite3_stmt *sqlstmt;
//rc = sqlite3_exec(db, query.c_str(), 0, 0, &errorMessage);

cout << "preparing statement"<<endl;
rc = sqlite3_prepare_v2(db, query.c_str(), 0, &sqlstmt, 0);
cout << "prepare code: "<<rc << endl;
if(rc != SQLITE_OK){
    sqlite3_close(db);
    return t_val;
}
cout << "Resetting call." <<endl;
rc = sqlite3_reset(sqlstmt);

cout << "about to start while"<<endl;
rc =sqlite3_step(sqlstmt);
cout << rc<<"|" << SQLITE_ROW <<"|" << SQLITE_OK <<"|"<<SQLITE_DONE<< endl;
while(rc == SQLITE_ROW){
    //sset retVal (id,name,code,typeId,reportTypeId,parentAsset);
    int id,typeID, reportTypeId;
    id = sqlite3_column_int(sqlstmt, 0);
    string name(reinterpret_cast<char const *>(sqlite3_column_text(sqlstmt, 1)));
    string code(reinterpret_cast<char const *>(sqlite3_column_text(sqlstmt, 2)));
    typeID = sqlite3_column_int(sqlstmt, 3);
    reportTypeId = sqlite3_column_int(sqlstmt, 4);
    string parentAsset(reinterpret_cast<const char *>(sqlite3_column_text(sqlstmt, 5)));
    cout <<"Fetched Asset Data: "<< id <<"|"<<name<<"|"<<code<<"|"<<typeID<<"|"<<reportTypeId<<"|"<<parentAsset << endl;
    Asset a (id, name, code, typeID, reportTypeId, parentAsset);
    retVal.push_back(a);
    rc = sqlite3_step(sqlstmt);
}
cout << "while ended, about to return."<<endl;
sqlite3_close(db);
return retVal;
}
4

1 に答える 1

2

を間違って呼び出していsqlite3_prepare_v2()ます。ドキュメントから:

nByte 引数がゼロより小さい場合、zSql は最初のゼロ ターミネータまで読み取られます。nByte が負でない場合、それは zSql から読み取られる最大バイト数です。nByte が負でない場合、zSql 文字列は最初の '\000' または '\u0000' 文字、または nByte 番目のバイトのいずれか早い方で終了します。

したがって、準備ステートメントは次のようになります (少なくとも最も簡単な変更)。

int rc = sqlite3_prepare_v2(
   db,
   query.c_str(),
   -1,   // instructs SQLITE to read the entire statement up to the \0 terminator
   &stmt,
   0);
于 2012-11-19T21:21:28.920 に答える