2013-07-31 85 views
8

我正在使用下面的代碼更新查詢使用sqlite
但我得到"database is locked error"
我試着搜索一些SO鏈接,並建議關閉數據庫,但是我又這樣做了同樣的錯誤。我已經提到了代碼中出現錯誤的地方。ios中的「數據庫鎖定」錯誤,同時更新查詢

const char *dbpath = [databasePath UTF8String]; 
if (sqlite3_open(dbpath, &database) == SQLITE_OK) 
{ 
    NSString *locationNo =NULL; 
    NSString *querySQL = [NSString stringWithFormat:@"select count(*) from code"]; 
    const char *query_stmt = [querySQL UTF8String]; 

    if (sqlite3_prepare_v2(database,query_stmt, -1, &statement, NULL) == SQLITE_OK) 
    { 
     if (sqlite3_step(statement) == SQLITE_ROW) 
     { 
      locationNo = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)]; 
      int count= [locationNo intValue]; 
      sqlite3_close(database); 
      NSLog(@"%@",locationNo); 
      if(0==count) 
      { 
       NSString *insertSQL = [NSString stringWithFormat:@"insert into favourite_code (code_id,code_1,code_2,code_3,code_4,code_5,code_6, status, record_status) VALUES (\"%d\",\"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\", \"%@\")",1 ,code1,code2,code3,code4,code5,code6,@"Y", @"Y"]; 

       const char *insert_stmt = [insertSQL UTF8String]; 
       sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL); 
       if (sqlite3_step(statement) == SQLITE_DONE) 
       { 
        return YES; 
       } 
       else { 
        return NO; 
       } 
       sqlite3_reset(statement); 
       sqlite3_close(database); 
      } 
      else{ 


       =========================== Getting Error in the below lines ========================= 

       const char *sq1l = "update code SET code_1=?, code_2=?, code_3=?, code_4=?, code_5=?,code_6=? WHERE code_id=1"; 

       if (sqlite3_prepare_v2(database, sq1l, -1, &statement, NULL) != SQLITE_OK) 
       { 
        NSLog(@"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database)); 
       } 
       else 
       { 
        sqlite3_bind_text(statement, 1, [code1 UTF8String], -1, SQLITE_TRANSIENT); 
        sqlite3_bind_text(statement, 2, [code1 UTF8String], -1, SQLITE_TRANSIENT); 
        sqlite3_bind_text(statement, 3, [code1 UTF8String], -1, SQLITE_TRANSIENT); 
        sqlite3_bind_text(statement, 4, [code1 UTF8String], -1, SQLITE_TRANSIENT); 
        sqlite3_bind_text(statement, 5, [code1 UTF8String], -1, SQLITE_TRANSIENT); 
        sqlite3_bind_text(statement, 6, [code1 UTF8String], -1, SQLITE_TRANSIENT); 

       } 

       int success = sqlite3_step(statement); 
       if (success != SQLITE_DONE) 
       { 
        NSLog(@"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database)); 
        //result = FALSE; 
       } 
       else 
       { 
        NSLog(@"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database)); 
        //result = TRUE; 
       } 

       =================================END========================================= 


      } 

      sqlite3_reset(statement); 
     } 
     else 
     { 
      NSLog(@"Not found"); 
      [email protected]"1"; 
     } 
     sqlite3_reset(statement); 
    } 
} 

回答

11

通常你會得到這個,如果你有多個查詢在同一時間回事(或者你沒有敲定一些早期的SQL語句,或者你有多個線程打開,或者你已經打開了數據庫中的多個次)。

此代碼有一個使用sqlite3_closesqlite3_reset(以及缺少sqlite3_finalize),這可能是問題的根源。

An Introduction To The SQLite C/C++ Interface,他們指出該語句的正確順序:

  • sqlite3_open(),打開數據庫
  • sqlite3_prepare(),準備一個SQL語句
  • sqlite3_bind(),將值綁定?根據需要
  • sqlite3_step()佔位符,以執行SQL和/或通過的結果
  • sqlite3_column(),步驟來檢索數據的列,根據需要
  • sqlite3_finalize(),完成/關閉準備的SQL語句
  • sqlite3_close() ,關閉數據庫

底線,你sqlite3_open呼叫未與一單到底sqlite3_close聲明匹配(但你必須外來sqlite3_close在你的代碼中)。此外,每個sqlite3_prepare_v2都必須有自己的sqlite3_finalize(如果要重置預準備語句,則只能使用sqlite3_reset,以便可以將其與新值綁定並再次逐步執行;但是當您完成準備工作時仍然需要sqlite3_finalize聲明)。

+0

感謝您的回答。我試過你說過的話。我刪除了sql_close,並只做finalize我刪除重置還仍然得到相同的錯誤。我是否正確?如果我錯了,請糾正我。 – 2vision2

+1

@ 2vision2關閉數據庫並用finalize替換重置是必要的步驟。但根本問題可能是你打開數據庫兩次。例如,你的代碼片段在開始時打開數據庫,但最後不會關閉它。如果你跑了兩次,你會遇到問題。確保你匹配你的開放和結束語句。確保每個'sqlite3_open'具有'sqlite3_close'並且每個'sqlite3_prepare_v2'具有'sqlite3_finalize'都非常重要。 – Rob

+0

@ 2vision2另外,您是否在這裏執行任何多線程代碼(例如GCD,'NSOperationQueue'或任何異步技術)?從多個線程/隊列訪問數據庫時必須特別小心。 – Rob