2013-07-31 35 views
8

Tôi đang sử dụng mã bên dưới để cập nhật truy vấn bằng cách sử dụng sqlite.
Nhưng tôi đang nhận được "database is locked error".
Tôi đã thử tìm kiếm một số liên kết SO và đề nghị đóng cơ sở dữ liệu, nhưng tôi lại làm như vậy lại nhận được lỗi tương tự. Tôi đã đề cập nơi tôi nhận được lỗi trong mã.Lỗi "cơ sở dữ liệu bị khóa" trong ios khi cập nhật truy vấn

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

Trả lời

11

Nói chung, bạn sẽ có được điều này nếu bạn có nhiều thắc mắc xảy ra cùng một lúc (hoặc bạn đã không hoàn thành một số câu lệnh SQL sớm, hoặc bạn có nhiều chủ đề mở, hoặc bạn đã mở nhiều cơ sở dữ liệu lần).

Mã này sử dụng hơi khó hiểu sqlite3_closesqlite3_reset (và thiếu sqlite3_finalize), có thể là nguồn gốc của sự cố.

Trong An Introduction To The SQLite C/C++ Interface, họ chỉ ra theo đúng thứ tự của các báo cáo:

  • sqlite3_open(), để mở một cơ sở dữ liệu
  • sqlite3_prepare(), để chuẩn bị một tuyên bố sql
  • sqlite3_bind(), để ràng buộc giá trị? placeholders khi cần thiết
  • sqlite3_step(), để thực thi sql và/hoặc duyệt qua kết quả
  • sqlite3_column(), để lấy các cột của dữ liệu, khi cần thiết
  • sqlite3_finalize(), để hoàn thành/đóng tuyên bố sql chuẩn bị
  • sqlite3_close() , đóng cửa cơ sở dữ liệu

Bottom line, gọi sqlite3_open của bạn không phù hợp với một sqlite3_close tuyên bố duy nhất ở cuối (nhưng bạn có một không liên quan sqlite3_close ở giữa mã của bạn). Ngoài ra, mỗi sqlite3_prepare_v2 phải có sqlite3_finalize riêng của mình (bạn chỉ sử dụng sqlite3_reset nếu bạn muốn đặt lại câu lệnh đã chuẩn bị để bạn có thể kết hợp nó với các giá trị mới và lặp lại nó, nhưng bạn vẫn cần sqlite3_finalize khi bạn đã hoàn tất việc chuẩn bị tuyên bố).

+0

Cảm ơn câu trả lời. Tôi đã thử bạn đã nói. Tôi đã gỡ bỏ sql_close và chỉ hoàn thành tôi đã gỡ bỏ thiết lập lại cũng vẫn đang nhận được lỗi tương tự. Tôi có làm đúng không? Vui lòng sửa tôi nếu sai. – 2vision2

+1

@ 2vision2 Việc đóng cơ sở dữ liệu và thay thế thiết lập lại bằng cách hoàn thành là các bước cần thiết. Nhưng vấn đề gốc có thể là bạn đang mở cơ sở dữ liệu hai lần. Ví dụ: đoạn mã của bạn mở cơ sở dữ liệu lúc bắt đầu nhưng không đóng nó ở cuối. Nếu bạn chạy điều này hai lần, bạn có vấn đề. Đảm bảo bạn khớp các câu lệnh mở và đóng của bạn. Nó rất quan trọng để đảm bảo mọi 'sqlite3_open' có một' sqlite3_close' và mỗi 'sqlite3_prepare_v2' đều có một' sqlite3_finalize'. – Rob

+0

@ 2vision2 Ngoài ra, bạn có đang thực hiện bất kỳ mã đa luồng nào ở đây không (ví dụ: GCD, 'NSOperationQueue' hoặc bất kỳ kỹ thuật không đồng bộ nào)? Cần chú ý đặc biệt khi truy cập cơ sở dữ liệu từ nhiều luồng/hàng đợi. – Rob

Các vấn đề liên quan