2012-08-26 4 views
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 문과 관계없이 데이터베이스는 각 업데이트에서 액세스됩니다. 단계 진술 때문에 그게 확실하지만, 제거하면 업데이 트가 발생하지 않습니다. 한 번에 모든 업데이트를 작성하겠습니다. sqlite3_exec을 사용하고 여전히 배열의 각 객체에 대한 변수를 바인드 할 수 있습니까? 아니면 성명서를 준비해야하는 다른 방법이 있습니까? 트랜잭션 내부가 어떤 모습인지 보여주는 예는 나에게 큰 도움이 될 것입니다!

답변

10

원하는대로 접근 방식을 사용할 수 있습니다. 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); 
+0

sqlite3_close (db)를 호출해야합니다. 거래 후? 내 경우에는 응용 프로그램의 작업을 통해 단 한 번만 db를 엽니 다. – Swati

+1

@ 스와 티 : 데이터베이스를 닫을 필요는 없습니다. 그 질문의 코드에서 오는 것입니다. db를 무기한으로 열어 두는 것이 좋습니다. 일반적으로 매우 일반적입니다. –