2015-04-03 71 views
0

我正確地打開和關閉數據庫。但仍然當我嘗試在表中插入記錄時,它給數據庫鎖定錯誤。請建議做什麼。iOS中的Sqlite數據庫鎖定問題

-(void)insertInDatabase:(NSMutableDictionary *) dict 
{ 

    NSArray *dbPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [dbPath objectAtIndex:0]; 
    NSString *DBPath=[documentsDirectory stringByAppendingPathComponent:@"InvoiceScannerDB.sqlite"]; 
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 
    [appDelegate checkAndCreateDatabase: DBPath]; 

    sqlite3 * database; 


    if(sqlite3_open([DBPath UTF8String], &database) == SQLITE_OK){ 
//  NSLog(@"open"); 
     NSString *sql = [[NSString alloc] initWithFormat:@"select * from Ticket where DELIVERY_SEQ='%@'and DOC_DATE='%@' and ROUTE_CODE='%@'", [dict valueForKey:@"DELIVERY_SEQ"],[dict valueForKey:@"DOC_DATE"],[dict valueForKey:@"ROUTE_CODE"]]; 


     sqlite3_stmt *statement, *statement1, *statement2; 

     if(sqlite3_prepare_v2(database, [sql UTF8String], -1, &statement, NULL) == SQLITE_OK){ 

      NSLog(@"sqlite3_prepare_v2: %s", sqlite3_errmsg(database)); 

       // NSLog(@"Statement %@",statement); 
      if(sqlite3_step(statement) == SQLITE_ROW){ 
       NSLog(@"statement: %s", sqlite3_errmsg(database)); 

        // Update Ticket for total scan count 
       NSLog(@"Same record found in local db"); 
       NSString *sqlUpdate = [[NSString alloc] initWithFormat:@"update Ticket set SCAN_INVOICE = '%ld' where DELIVERY_SEQ='%@'and DOC_DATE='%@' and ROUTE_CODE='%@'", (long)[[dict valueForKey:@"SCAN_INVOICE"] integerValue], [dict valueForKey:@"DELIVERY_SEQ"], [dict valueForKey:@"DOC_DATE"], [dict valueForKey:@"ROUTE_CODE"]]; 
       if(sqlite3_prepare_v2(database, [sqlUpdate UTF8String], -1, &statement2, NULL) == SQLITE_OK){ 

        sqlite3_step(statement2); 
         //     NSLog(@"Scan count updated successfully"); 

       } 
       else{ 
        NSLog(@"Not updated data"); 
       } 
       sqlite3_finalize(statement2); 
      } 
      else { 
        // Insert 
       NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
       dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; 
       [dateFormatter setDateFormat:@"dd-MMM-yyyy"]; 
       NSString *newDateString = [dateFormatter stringFromDate:[NSDate date]]; 

       NSString *sqlInsert = [[NSString alloc] initWithFormat:@"insert into Ticket (DELIVERY_SEQ, DOC_DATE, ROUTE_CODE, TOTAL_INVOICE, SCAN_INVOICE, InsertedDate) values('%@','%@', '%@','%ld','%ld', '%@')", [dict valueForKey:@"DELIVERY_SEQ"], [dict valueForKey:@"DOC_DATE"], [dict valueForKey:@"ROUTE_CODE"], (long)[[dict valueForKey:@"TOTAL_INVOICE"] integerValue], (long)[[dict valueForKey:@"SCAN_INVOICE"] integerValue], newDateString]; 

       NSLog(@"Insertion Query %@", sqlInsert); 

       if(sqlite3_prepare_v2(database, [sqlInsert UTF8String], -1, &statement1, NULL) == SQLITE_OK){ 

        if(sqlite3_step(statement1) == SQLITE_DONE) 
        { 

        } else { 
         NSLog(@"error: %s", sqlite3_errmsg(database)); 
        } 
       } 
       else{ 
         NSLog(@"Not inserted data"); 
       } 
       sqlite3_finalize(statement1); 
      } 
     } 
     else{ 
      NSLog(@"COULD NOT OPEN DB"); 
     } 
     sqlite3_finalize(statement); 
    } 
    sqlite3_close(database); 


} 

請幫助我在這個問題上

+0

試試這個[link](http://stackoverflow.com/questions/8853954/sqlite-error-database-is-locked)可能是你的希望 – 2015-04-03 05:09:01

+1

在哪一行你必須得到錯誤。 – 2015-04-03 05:41:41

+0

一旦檢查您的方法調用,是在不同的線程或主線程 – 2015-04-03 07:07:53

回答

1

您正在執行statement1statement2你完成原來statement之前。在嘗試執行INSERTUPDATE之前,您應該關閉第一個SELECT語句,該語句用於測試是否有任何數據行。這可能不是繁忙的數據庫錯誤的實際來源,但它是一個很好的例子,說明在同一時間意外(和不必要地)執行兩條SQL語句是多麼容易。

如果修復此錯誤不會消除錯誤,那麼您必須擁有一些鎖定數據庫的其他代碼。我知道你向我們保證,你已經檢查了所有的開放和關閉的聲明,並且你沒有任何多線程數據庫交互,但是「繁忙」的消息意味着數據庫只是在忙着做別的事情,所以你有弄清楚這是什麼。

如果問題仍然存在,我可能會建議集中打開/關閉數據庫(這樣就很容易插入「它已經打開」檢查)。坦率地說,我可能會更進一步,取消爲每個數據庫交互打開和關閉數據庫的過程,但這取決於您。

+0

感謝您的寶貴意見。現在我正在使用單語句和重置語句來重用它。現在工作正常。 – user1589516 2015-04-10 03:57:33