0

私は次のことをしようとしました。

レコードを追加した後、同じテーブルから選択して、自動インクリメントと主キーであるユーザー ID を取得します。しかし、次のことをしようとするとセグメンテーションコアダンプが発生します

挿入コードは機能しますが、select ステートメントを実行しようとすると、コードでエラーが発生します。データベースからユーザー ID フィールドを取得し、それを文字列またはベクトルの結果 [0] に割り当てようとしています。

私のtest2.cppコード:

#include <iostream>
#include <sqlite3.h>
#include <vector>

//g++ -o test2 test2.cpp -lsqlite3
using namespace std;

string quotesql( const string& s ) {
    return string("'") + s + string("'");
}


int main()
{
int counter = 0;

    sqlite3 *db;
    sqlite3_stmt * stmt, * stmt2;

string name = "Kungfu Panda2";
string department = "normal";
string password = "hellopassword";

string sqlstatement = "INSERT INTO abe_account (name,department,password) VALUES ("
+quotesql(name) + ","
+quotesql(department) + ","
+quotesql(password) + ");";


    if (sqlite3_open("abeserver.db", &db) == SQLITE_OK)
    {
    sqlite3_prepare( db, sqlstatement.c_str(), -1, &stmt, NULL );//preparing the statement
    sqlite3_step( stmt );//executing the statement
        }
    else
    {
        cout << "Failed to open db\n";
    }

    sqlite3_finalize(stmt);

//after insert ,we select back to get the user id;

sqlstatement = "select * from abe_account where name="
+quotesql(name) + " AND department=" 
+quotesql(department)+";";

    sqlite3_prepare( db, sqlstatement.c_str(), -1, &stmt2, NULL );//preparing the statement
    sqlite3_step( stmt2 );//executing the statement


std::vector< std::vector < std:: string > > result;

while( sqlite3_column_text( stmt2, 0 ) )
{
    for( int i = 0; i < 4; i++ )
    result[i].push_back( std::string( (char *)sqlite3_column_text( stmt2, i ) ) );
    sqlite3_step( stmt2 );
}


   //cout << result.size() << endl;



    sqlite3_finalize(stmt2);
    sqlite3_close(db);





    return 0;

}

正常に追加した場合、データを取得するにはどうすればよいですか。ステートメントが正しく実行されていることを確認するために取得する必要があります。また、ユーザー ID が +userid+ であることをクライアントに伝える必要があるため、自動インクリメントされ、主キーとして作成されたユーザー ID を取得する必要があります。

select ステートメントのベクトルの使用法が間違っている場合、insert ステートメントの実行後にユーザー ID を取得するにはどうすればよいですか? データベースをチェックすると、insert ステートメントが機能し、レコードが追加されました

4

2 に答える 2

0

問題はこの呼び出しです:

result[i].push_back(...);

resultはベクトルのベクトルですが、空です。したがって、使用しようとするとresult[i]失敗します。

編集:

代わりに、内側のループを次のように変更します。

for( int i = 0; i < 4; i++ )
{
    result.push_back(vector<std::string>());
    result[i].push_back(...);
}

たぶん、代わりに次のようなことを意味します。

for (int i = 0; sqlite3_column_text(stmt2, 0); i++ )
{
    result.push_back(vector<std::string>());

    for (int j = 0; j < 4; j++)
        result[i].push_back(...);

    sqlite_step(stmt2);
}
于 2012-08-14T11:16:00.457 に答える
0

初期化されていないネストされた s の問題に加えてvector(Joachim Pileborg の回答を参照)、sqlite3_column_textループ状態での結果を確認しないでください。SQLiteのドキュメントには次のように記載されています。

SQL ステートメントが現在有効な行を指していない場合、または列インデックスが範囲外である場合、結果は未定義です。

sqlite3_step次のように、 while 条件の結果を確認したいと思います。

std::vector< std::vector < std:: string > > result;

while(sqlite3_step(stmt2) == SQLITE_ROW)
{
    result.push_back(vector<std::string>());

    for( int i = 0; i < 4; i++ )
    {
         result[i].push_back( std::string( (char *)sqlite3_column_text( stmt2, i ) ) );
    }
}

このアプローチを使用する場合はsqlite3_step、ループの上の数行を削除する必要があります。

于 2012-08-14T11:46:57.287 に答える