2
我想遍歷一個對象數組,並根據ID在SQLite數據庫中更新相應的行。我想在一次交易中做到這一點。我知道我可以使用:iOS的SQLite事務語法
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語句如何,數據庫都在每個Update上訪問。我很確定這是因爲步驟聲明,但如果我刪除它,更新不會發生。我希望一次寫入所有更新。是否有可能使用sqlite3_exec並仍爲數組中的每個對象綁定變量?或者,我應該準備這份聲明有不同的方式嗎?任何交易內部應該看起來像什麼的例子都會對我有很大的幫助!
是否需要調用sqlite3_close(db);交易完成後在我的情況下,我只在應用程序的整個工作過程中打開db一次。 – Swati
@Swati:沒有必要關閉數據庫;來自問題中的代碼。無限期地開放分貝是完全可以的,而且很常見。 –