2

オブジェクトの配列をループして、IDに従ってSQLiteデータベースの対応する行を更新したいと思います。これを1回のトランザクションで実行したいと思います。私は使用できることを知っています:

sqlite3_exec(db, "BEGIN", 0, 0, 0);
sqlite3_exec(db, "COMMIT", 0, 0, 0);

ただし、トランザクション内で更新ステートメントをコーディングする方法がわかりません。さまざまな変数をステートメントにバインドする必要があります。現在、コードは次のようになっています。

-(void)someUpdateMethod
{
    sqlite3 *db;

    //Establish connection to db
    if (sqlite3_open([[self dbFilePath] UTF8String], &db) == SQLITE_OK)
    {
        const char *query = "UPDATE Table SET Value1 = ?, Value2 = ?";

        sqlite3_stmt *compiledStatement = nil;

        sqlite3_exec(db, "BEGIN EXCLUSIVE TRANSACTION", 0, 0, 0);
        for (someObject *obj in uArray)
        {
            // Repeated statement - This is what I'm not sure of...
            if(sqlite3_prepare(db, query, -1, &compiledStatement, NULL) == SQLITE_OK)
            {
                sqlite3_bind_int(compiledStatement, 1, [obj value1]);
                sqlite3_bind_int(compiledStatement, 2, [obj value2]);
            }
            if (sqlite3_step(compiledStatement) != SQLITE_DONE) NSLog(@"DB not updated. Error: %s",sqlite3_errmsg(db));
            if (sqlite3_finalize(compiledStatement) != SQLITE_OK) NSLog(@"SQL Error: %s",sqlite3_errmsg(db));
        }
        if (sqlite3_exec(db, "COMMIT TRANSACTION", 0, 0, 0) != SQLITE_OK) NSLog(@"SQL Error: %s",sqlite3_errmsg(db));
        sqlite3_close(db);
    }
    else
    NSLog(@"sql-error: %s", sqlite3_errmsg(db));
}

BeginステートメントとCommitステートメントに関係なく、データベースは各更新でアクセスされます。これはstepステートメントによるものだと確信していますが、削除しても更新は行われません。すべてのアップデートを一度に書いてほしい。sqlite3_execを使用しても、配列内の各オブジェクトの変数をバインドすることは可能ですか?または、ステートメントを準備する別の方法はありますか?トランザクションの内部がどのように見えるかについての例は、私にとって大きな助けになります!

4

1 に答える 1

14

あなたのアプローチはあなたが望むように機能します。sqliteがディスクにアクセスしていても、コミットするまで更新は他のトランザクションに表示されません。ですから、そういう意味では「一気に書かれている」のです。

準備をループの外に移動すると、コードが少し効率的になる可能性があります。これを行う場合はsqlite3_reset、ループ内とループのsqlite3_finalize後に使用します。

  sqlite3_exec(db, "BEGIN EXCLUSIVE TRANSACTION", 0, 0, 0);
  if(sqlite3_prepare(db, query, -1, &compiledStatement, NULL) == SQLITE_OK)
  {
    for (someObject *obj in uArray)
    {
        sqlite3_bind_int(compiledStatement, 1, [obj value1]);
        sqlite3_bind_int(compiledStatement, 2, [obj value2]);
        if (sqlite3_step(compiledStatement) != SQLITE_DONE) NSLog(@"DB not updated. Error: %s",sqlite3_errmsg(db));
        if (sqlite3_reset(compiledStatement) != SQLITE_OK) NSLog(@"SQL Error: %s",sqlite3_errmsg(db));
    }
  }
  if (sqlite3_finalize(compiledStatement) != SQLITE_OK) NSLog(@"SQL Error: %s",sqlite3_errmsg(db));
  if (sqlite3_exec(db, "COMMIT TRANSACTION", 0, 0, 0) != SQLITE_OK) NSLog(@"SQL Error: %s",sqlite3_errmsg(db));
  sqlite3_close(db);
于 2012-08-27T01:59:57.813 に答える