2012-06-10 3 views
1

내 SqlLite 데이터베이스에서 데이터를 삭제하려고하면 내 앱이 다운 됨.iphone에서 데이터 sqllite 삭제 - 데이터베이스 잠김

이 오류입니다 : Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error while deleting. 'database is locked'

이 데이터베이스에있는 모든 내 코드입니다 : 어떤 제안

#import "Database.h" 

static sqlite3 *database = nil; 
static sqlite3_stmt *deleteStmt = nil; 
static sqlite3_stmt *addStmt = nil; 

@implementation Database 

@synthesize id_poi, pathDb, arrPoi; 

- (id) initWithData:(NSDictionary *) data { 

    [super init]; 
    NSLog(@"%@",[data objectForKey:@"pathDb"]); 
    NSLog(@"id_poi = %@",[data objectForKey:@"id_poi"]); 
    //setto l'id nello stato dell'oggetto 
    id_poi = [data objectForKey:@"id_poi"]; 
    pathDb = [data objectForKey:@"pathDb"]; 

    return self; 
} 

- (void) deletePoi { 

    if (sqlite3_open([pathDb UTF8String], &database) == SQLITE_OK) { 
     const char *sql = "delete from Poi where id_poi = ?"; 
     sqlite3_stmt *deleteStmt; 
     if(sqlite3_prepare_v2(database, sql, -1, &deleteStmt, NULL) == SQLITE_OK) { 
      //When binding parameters, index starts from 1 and not zero. 
      sqlite3_bind_int(deleteStmt, 1, [id_poi integerValue]); 

      if (SQLITE_DONE != sqlite3_step(deleteStmt)) { 
       NSAssert1(0, @"Error while deleting. '%s'", sqlite3_errmsg(database)); 
       [[WPActivityIndicator sharedActivityIndicator] hide]; 
       return; 
      } 
     } else { 
      NSAssert1(0, @"Error while creating delete statement. '%s'", sqlite3_errmsg(database)); 
     } 
     sqlite3_finalize(deleteStmt); 
    } else { 
     sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory. 
    } 


    [[WPActivityIndicator sharedActivityIndicator] hide]; 
} 

- (BOOL) checkIdPoi { 

    // lista temporanea 
    NSMutableArray *listaTemp = [[NSMutableArray alloc] init]; 
    // Oggetto che contiene i vari elementi 
    NSMutableDictionary *dictionary; 

    NSMutableString *str_id_poi;//id della persona 

    if (sqlite3_open([pathDb UTF8String], &database) == SQLITE_OK) { 
     // query che ricava i valori 
     const char *sql = "select id_poi from Poi where id_poi = ?"; 
     sqlite3_stmt *selectstmt; 

     if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) { 

      sqlite3_bind_int(selectstmt, 1 , [id_poi integerValue]); 
      while(sqlite3_step(selectstmt) == SQLITE_ROW) { 
       // ricaviamo i valori letti dalla query 
       str_id_poi = [NSMutableString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)]; 

       // inseriamo tutti i valori letti in un unico oggetto 
       dictionary = [[NSMutableDictionary alloc] initWithObjectsAndKeys:str_id_poi, @"id_poi", nil]; 
       //NSLog(@"str_id_poi = %@",str_id_poi); 
       [listaTemp addObject:dictionary]; 
       [dictionary release]; 
       return TRUE; 
      } 
     } else { 
      NSAssert1(0, @"Error while read data. '%s'", sqlite3_errmsg(database)); 
      return FALSE; 
     } 
    } 
    else { 
     sqlite3_close(database); 
     return FALSE; 
    } 

    return FALSE; 

} 

- (void) addPoi { 

    //NSLog(@"%@",pathDb); 

    if (sqlite3_open([pathDb UTF8String], &database) == SQLITE_OK) { 

     const char *sql = "insert into Poi(id_poi) Values(?)"; 
     sqlite3_stmt *addStmt; 
     if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) == SQLITE_OK) { 

      NSString *str_id_poi = [[NSString alloc] initWithFormat:@"%d", [id_poi integerValue]]; 
      sqlite3_bind_text(addStmt, 1, [str_id_poi UTF8String], -1, SQLITE_TRANSIENT); 

      if(SQLITE_DONE != sqlite3_step(addStmt)) { 
       NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database)); 
       [[WPActivityIndicator sharedActivityIndicator] hide]; 
       return; 
      } else { 
       //SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid 
       //id_poi = sqlite3_last_insert_rowid(database); 
      } 

      //Reset the add statement. 
      sqlite3_reset(addStmt); 


     } else { 
      NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database));    
     } 
     sqlite3_finalize(addStmt); 

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

    sqlite3_close(database); 

    [[WPActivityIndicator sharedActivityIndicator] hide]; 

} 

// Carica i valori dal database passato come parametro 
-(NSMutableArray*)getIdPOI { 

    // lista temporanea 
    NSMutableArray *listaTemp = [[NSMutableArray alloc] init]; 
    // Oggetto che contiene i vari elementi 
    NSMutableDictionary *dictionary; 

    NSMutableString *str_id_poi;//id della persona 

    if (sqlite3_open([pathDb UTF8String], &database) == SQLITE_OK) { 
     // query che ricava i valori 
     const char *sql = "select id_poi from Poi"; 
     sqlite3_stmt *selectstmt; 

     if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) { 

      while(sqlite3_step(selectstmt) == SQLITE_ROW) { 
       // ricaviamo i valori letti dalla query 
       str_id_poi = [NSMutableString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 0)]; 

       // inseriamo tutti i valori letti in un unico oggetto 
       dictionary = [[NSMutableDictionary alloc] initWithObjectsAndKeys:str_id_poi, @"id_poi", nil]; 
       //NSLog(@"str_id_poi = %@",str_id_poi); 
       [listaTemp addObject:dictionary]; 
       [dictionary release]; 
      } 

      //Reset the add statement. 
      sqlite3_reset(selectstmt); 

     } else { 
      NSAssert1(0, @"Error while read data. '%s'", sqlite3_errmsg(database)); 
     } 

     //ADD THIS LINE TO YOUR CODE 
     sqlite3_finalize(selectstmt); 
    } 
    else 
     sqlite3_close(database); 

    sqlite3_close(database); 

    return listaTemp; 
} 


+ (void) finalizeStatements { 
    if(database) sqlite3_close(database); 
    if(deleteStmt) sqlite3_finalize(deleteStmt); 
    if(addStmt) sqlite3_finalize(addStmt); 
} 


-(void)dealloc { 
    [pathDb release]; 
    [arrPoi release]; 

    [super dealloc]; 
} 

@end 

?

+0

함수 deletePoi 및 checkIdPoi에 닫기 데이터베이스 호출이 없습니다. 그것은 아마도 당신의 문제의 원인 일 것입니다. BTW, 데이터베이스를 열 때 오류가 발생하면 다른 함수에서 sqlite_close를 두 번 호출합니다. – Stefan

답변

1

이것은 일반적으로 데이터베이스를 연 다음 제대로 닫지 않은 경우에 발생합니다. 다른 곳에서 열어 본 데이터베이스의 인스턴스가 동일하기 때문일 수 있습니다 (다른 클래스 또는 SQLite 관리자와 동일).

일반적으로 데이타베이스를 열고 닫는 대신 데이타베이스와 통신하는 싱글 톤 인스턴스를 작성하는 것이 좋습니다. 이것이 도움이되기를 바랍니다.

2

이 유형의 오류는 sqlite db에 대해 하나 이상의 쿼리가 실행될 때 발생할 수 있습니다. 쿼리를 실행할 때 데이터베이스에 대한 모든 호출을 동기화해야합니다. 그래서 같은 @synchronized 블록

랩의 모든 데이터베이스 코드 :

@synchronized(self) 
{ 
    // database query code goes here 
} 

NB. 이 예제에서는 모든 데이터베이스 쿼리가 1 클래스 내부에서 실행된다고 가정합니다. 그렇지 않으면 'self'를 데이터베이스와 인터페이스하는 모든 클래스가 공유하는 공통 오브젝트 인스턴스로 바꿔야합니다. 또는 주 스레드에서 모든 데이터베이스 문을 실행할 수 있습니다.

+0

데이터베이스를 동기화하는 방법은 무엇입니까? 이 post - above 문에서 – Dany

+0

은 synchronized 문을 사용하여 데이터베이스를 잠급니다. – ruyamonis346

+0

즉 해당 방식으로 데이터베이스에 대한 모든 호출을 래핑하십시오. –

관련 문제