2013-07-31 21 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_closeの使用とsqlite3_reset(とsqlite3_finalizeの欠如)を、持っています。 An Introduction To The SQLite C/C++ Interface

、彼らは文の正しい順序を指摘:

  • sqlite3_open()、に値をバインドするために、SQL文
  • sqlite3_bind()を準備するために、データベース
  • sqlite3_prepare()を開くために?
  • sqlite3_step()、/準備されたSQL文
  • sqlite3_close()を閉じる完了し、必要な
  • sqlite3_finalize()として、データの列を取得するには、SQLを実行し、および/または結果を通じて
  • sqlite3_column()をステップに、必要に応じてプレースホルダ、データベース

ボトムラインを閉じるには、あなたのsqlite3_openコールを最後に、単一のsqlite3_closeの文と一致する(しかし、あなたは余分なを持っていませんあなたのコードの真中にある)。また、sqlite3_prepare_v2にはそれぞれsqlite3_finalizeが必要です(プリペアドステートメントをリセットして新しい値をバインドして再度実行できるようにする場合はsqlite3_resetのみを使用しますが、準備が完了した時点でまだsqlite3_finalizeが必要です)ステートメント)。

+0

お返事ありがとうございます。私はあなたが言ったことを試みた。私はsql_closeを削除し、私は同じエラーを取得しているリセットを削除して確定しただけでした。私は正しいことをしていますか?間違っている場合は私を修正してください。 – 2vision2

+1

@ 2vision2データベースを閉じて、リセットをfinalizeに置き換えることは、必要な手順です。しかし、根本的な問題はおそらく、データベースを2回開いているということです。たとえば、コードスニペットはデータベースを最初に開きますが、最後には閉じません。これを2回実行すると、問題が発生します。開いている文と閉じる文が一致していることを確認してください。すべての 'sqlite3_open'に' sqlite3_close'があり、 'sqlite3_prepare_v2'には' sqlite3_finalize'があることを確認することが非常に重要です。 – Rob

+0

@ 2vision2また、ここでマルチスレッドコードを実行していますか(GCD、NSOperationQueue、またはその他の非同期技術など)?複数のスレッド/キューからデータベースにアクセスする場合は、特別な注意が必要です。 – Rob

関連する問題