2011-04-14 16 views
12

Estoy desarrollando una aplicación para iPhone, al insertar datos en la base de datos llegué "Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error while inserting data. 'database is locked''" Error. El código es:base de datos está bloqueado en SQLite

- (NSString *) getDBPath {   
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES); 
     NSString *documentsDir = [paths objectAtIndex:0]; 
     return [documentsDir stringByAppendingPathComponent:@"Halal.sqlite"]; 
} 

+ (void) finalizeStatements { 

      if (database) sqlite3_close(database); 
      if (deleteStmt) sqlite3_finalize(deleteStmt); 
      if (addStmt) sqlite3_finalize(addStmt); 
      if (detailStmt) sqlite3_finalize(detailStmt); 
      if (updateStmt) sqlite3_finalize(updateStmt); 
} 

- (void) gettingData:(NSString *)dbPath { 

      NSLog(@"Data base path is %@",dbPath); 
      if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) 
      { 
       const char *sql = "select * from Product"; 
       sqlite3_stmt *selectstmt; 
       if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) 
       { 
        while(sqlite3_step(selectstmt) == SQLITE_ROW) 
        { 
     [membersInfoDict setValue:[NSString stringWithUTF8String:(char*)sqlite3_column_text(selectstmt, 0)] forKey:@"ProductName"]; 
         [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)] forKey:@"ProductBarcode"]; 
         [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)] forKey:@"ProductImage"]; 
         [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 3)] forKey:@"ProductIngredients"]; 
         [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 4)] forKey:@"ProductStatus"]; 


         if(membersInfoDict) 
         { 
          [membersInfoArray addObject:membersInfoDict]; 
          membersInfoDict = nil; 
         // NSLog(@"Entered and return"); 
          return; 
         } 
        } 
       }    
      } 

      else 
       sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory. 

} 


- (void) addRecord:(NSMutableDictionary *)recordDict 
{ 
      if (sqlite3_close(database)) 
      { 
       NSLog(@"Closed"); 
       NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES); 
       NSString *documentsDir = [paths objectAtIndex:0]; 

       [self gettingData:[documentsDir stringByAppendingPathComponent:@"Halal.sqlite"]];     
      } 
      else { 
       NSLog(@"Not Closed"); 
      }    
      if(addStmt == nil) { 
       const char *sql = "insert into Product(ProductName, ProductBarcode , ProductImage,ProductIngredients,ProductStatus) Values(?,?,?,?,?)"; 
       if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK) 
        NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database)); 
      } 

      sqlite3_bind_text(addStmt, 1, [[recordDict objectForKey:@"ProductName"] UTF8String], -1, SQLITE_TRANSIENT); 
      sqlite3_bind_text(addStmt, 2, [[recordDict objectForKey:@"ProductBarcode"] UTF8String], -1, SQLITE_TRANSIENT); 
      sqlite3_bind_text(addStmt, 3, [[recordDict objectForKey:@"ProductImage"] UTF8String], -1, SQLITE_TRANSIENT); 
      sqlite3_bind_text(addStmt, 4, [[recordDict objectForKey:@"ProductIngredients"] UTF8String], -1, SQLITE_TRANSIENT); 
      sqlite3_bind_text(addStmt, 5, [[recordDict objectForKey:@"ProductStatus"] UTF8String], -1, SQLITE_TRANSIENT); 


      if(SQLITE_DONE != sqlite3_step(addStmt)) 
       NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database)); 
      else 
      //SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid 
       rowID = sqlite3_last_insert_rowid(database); 
      NSLog(@"last inserted rowId = %d",rowID); 

      //Reset the add statement. 
      sqlite3_reset(addStmt); 
      //sqlite3_commit_hook(); 
      //sqlite3_commit_hook(addStmt,[NSString stringWithFormat:@"%d",rowID],database); 

} 

Por favor, dame solución para esto. Muchas gracias ...

+0

donde está abriendo ["base de datos" sqlite3 *] y ¿hay alguna otra consulta que haya utilizado y todavía la mantiene abierta? – Ravin

+0

Estoy abriendo la base de datos al mostrar los detalles – Anand

Respuesta

18

//ADD THIS LINE TO YOUR CODE en el siguiente método modificado el tuyo.

- (void) gettingData:(NSString *)dbPath { 
    NSLog(@"Data base path is %@",dbPath); 
    if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) 
    { 
     const char *sql = "select * from Product"; 
     sqlite3_stmt *selectstmt; 
     if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) 
     { 
      while(sqlite3_step(selectstmt) == SQLITE_ROW) 
      { 
       [membersInfoDict setValue:[NSString stringWithUTF8String:(char*)sqlite3_column_text(selectstmt, 0)] forKey:@"ProductName"]; 
       [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)] forKey:@"ProductBarcode"]; 
       [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)] forKey:@"ProductImage"]; 
       [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 3)] forKey:@"ProductIngredients"]; 
       [membersInfoDict setValue:[NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 4)] forKey:@"ProductStatus"]; 

       if(membersInfoDict) 
       { 
        [membersInfoArray addObject:membersInfoDict]; 
        membersInfoDict = nil; 
        // NSLog(@"Entered and return"); 
        sqlite3_close(database); 
        return; 
       } 
      } 
     } 
     //ADD THIS LINE TO YOUR CODE 
     sqlite3_finalize(selectstmt); 
    }   
    else 
     sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory. 
} 
+1

En caso (membersInfoDict) está regresando sin soltar la base de datos. Deberás incluir un sqlite3_close allí. – Vincent

+0

@Vincent Thanks Vincent – rptwsthi

+0

@Vincent ¿Deberías cerrar el db cada vez que accedas? Además, uso un método [self openDB] para abrir el DB. ¿Importa que separe la funcionalidad o debería hacer todas las cosas en el mismo lugar? Parece que no debería importar. – SonOfSeuss

9

tiene que finalizar las declaraciones compiladas y luego cerrar la base de datos antes de abrirla de nuevo.

sqlite3_finalize(compiledStatement); 
sqlite3_close(database); 
4

Las respuestas anteriores son correctas, sin embargo hay una manera de la que muestran la base de datos de error de bloqueo, si estamos trabajando o la depuración en simuladores.

Caso 1:

Aquí estoy explicando un escenario al insertar datos en una tabla. Y esa base de datos está accediendo desde cualquier navegador de base de datos y accediendo desde el simulador.

Ahora cuando está trabajando en la aplicación a través del simulador, como guardó los datos de la base de datos guardados. Ahora si está utilizando cualquier navegador para acceder a los datos de esa base de datos y si activa cualquier comando de actualización en su navegador e intenta actualizar cualquier fila, actualiza esa fila en una tabla. (Ahora, cuando intentamos eliminar algo de la tabla, siempre se muestra un mensaje que en los permisos de solo lectura del navegador se otorgan, etc.).

Ahora vamos al simulador o si ejecuta la aplicación nuevamente y cuando intenta insertar cualquier dato en esa tabla, siempre muestra el error 'La base de datos está bloqueada' porque los permisos son de solo lectura y los atemperamos permisos Ahora bien, si intenta cambiar los comandos como se menciona en las respuestas, siempre obtendrá tristeza. Siempre muestra un error de la base de datos está bloqueada (como he intentado varias veces para resolver esto, pero cada vez que fallé).

Solo hay una manera de eliminar esta situación: eliminar la aplicación de su simulador y volver a instalarla. Y evite actualizar/insertar cualquier fila del navegador.

Otra respuesta es: Caso 2:

Como se está trabajando en el navegador sqlite y realizar los updations de ella, asegúrese de que ha guardado todos los cambios otra condición sabia bloqueado sucede.

Cuestiones relacionadas