2013-07-31 7 views
8

Ich verwende den folgenden Code , um die Abfrage mit sqlite zu aktualisieren.
Aber ich bekomme "database is locked error".
Ich habe versucht, einige SO-Link und es wurde vorgeschlagen, die Datenbank zu schließen, aber ich habe das wieder den gleichen Fehler bekommen. Ich habe erwähnt, wo ich Fehler im Code bekomme."Datenbank gesperrt" -Fehler in ios beim Aktualisieren der Abfrage

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); 
    } 
} 

Antwort

11

der Regel werden Sie dies, wenn man sich gleichzeitig los mehrere Anfragen haben (entweder Sie nicht einige frühe SQL-Anweisung abzuschließen haben, oder Sie haben mehrere Threads öffnen, oder Sie haben die Datenbank mehrere geöffnet mal).

Dieser Code hat eine etwas verwirrende Verwendung von sqlite3_close und sqlite3_reset (und einen Mangel an sqlite3_finalize), die die Ursache des Problems sein könnte.

In An Introduction To The SQLite C/C++ Interface weisen sie die richtige Reihenfolge der Aussagen aus:

  • sqlite3_open(), eine Datenbank zu öffnen
  • sqlite3_prepare(), eine SQL-Anweisung
  • sqlite3_bind(), vorzubereiten zu binden Werte? falls erforderlich
  • sqlite3_step() Platzhalter, die SQL-und/oder Schritt durch die Ergebnisse
  • sqlite3_column(), auszuführen, um die Spalten von Daten abzurufen, falls erforderlich
  • sqlite3_finalize(), abzuschließen/Schließen der vorbereitete SQL-Anweisung
  • sqlite3_close() zu schließen, wird die Datenbank

Unterm Strich Ihres sqlite3_open Anruf nicht mit einer einzigen sqlite3_close Erklärung am Ende angepasst (aber Sie haben ein Fremd sqlite3_close in der Mitte Ihres Codes). Außerdem muss jede sqlite3_prepare_v2 ihre eigene sqlite3_finalize haben (Sie verwenden nur sqlite3_reset, wenn Sie eine vorbereitete Anweisung zurücksetzen möchten, damit Sie sie mit neuen Werten verknüpfen und erneut durchlaufen können; aber Sie benötigen immer noch sqlite3_finalize, wenn Sie fertig sind Erklärung).

+0

Danke für die Antwort. Ich habe versucht, was du gesagt hast. Ich entfernte sql_close und habe nur abgeschlossen Ich entfernte Reset auch immer noch bekomme den gleichen Fehler. Mache ich es richtig? Bitte korrigiere mich, wenn ich falsch liege. – 2vision2

+1

@ 2vision2 Das Schließen der Datenbank und das Ersetzen der Zurücksetzung durch Finalisieren sind notwendige Schritte. Das Hauptproblem besteht jedoch wahrscheinlich darin, dass Sie die Datenbank zweimal öffnen. Beispielsweise öffnet Ihr Code-Snippet die Datenbank beim Start, schließt sie aber am Ende nicht. Wenn Sie das zweimal ausführen würden, hätten Sie Probleme. Stellen Sie sicher, dass Sie Ihre Open- und Close-Anweisungen aufeinander abstimmen. Es ist sehr wichtig sicherzustellen, dass jedes 'sqlite3_open' ein' sqlite3_close' hat und dass jedes 'sqlite3_prepare_v2' ein' sqlite3_finalize' hat. – Rob

+0

@ 2vision2 Machst du hier auch einen Multi-Thread-Code (z. B. GCD, 'NSOperationQueue' oder irgendwelche asynchronen Techniken)? Beim Zugriff auf eine Datenbank aus mehreren Threads/Queues muss besonders vorsichtig vorgegangen werden. – Rob

Verwandte Themen