2013-07-31 4 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(), чтобы открыть базу данных
  • 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 и сделал только финализацию, я удалил сброс, но все равно получаю ту же ошибку. Правильно ли я делаю это? Пожалуйста, поправьте меня, если я ошибаюсь. – 2vision2

+1

@ 2vision2 Закрытие базы данных и замена сброса завершением являются необходимыми шагами. Но проблема с корнем, вероятно, заключается в том, что вы дважды открываете базу данных. Например, ваш фрагмент кода открывает базу данных в начале, но не закрывает ее в конце. Если вы запустите это дважды, у вас возникнут проблемы. Убедитесь, что вы сопоставляете свои открытые и закрытые заявления. Очень важно убедиться, что каждый 'sqlite3_open' имеет' sqlite3_close' и что каждый 'sqlite3_prepare_v2' имеет' sqlite3_finalize'. – Rob

+0

@ 2vision2 Также вы делаете здесь многопоточный код (например, GCD, NSOperationQueue или любые асинхронные методы)? Особое внимание следует уделять при доступе к базе данных из нескольких потоков/очередей. – Rob

Смежные вопросы