2011-05-10 61 views
2

編輯:已解決!回答下面的第一個代碼框SQLite表不存在

當我嘗試連接一個sqlite數據庫(與表TblTest)。在我的應用程序調試模式,錯誤的是:

*在斷言失敗 - [QueryClass getTestData:], *終止應用程序由於未捕獲的異常「NSInternalInconsistencyException」,理由是:「廣東話建立SQL讀取項目[沒有這樣的表格:TblTest]'

在發佈模式(模擬器)中,它不會給出錯誤,但它不會讀取數據庫。 代碼的行爲就像它可以連接到數據庫,但不能讀取TblTest?

我已經重置了模擬器並使用了clean和build。

很抱歉的長碼:

@implementation QueryClass 
@synthesize databaseName; 
@synthesize databaseLite; 

-(id)initWithDatabase:(NSString *)databaseNameP{ 
    if(self = [super init]){ 
     [self createEditableCopyOfDatabaseIfNeeded]; 
     self.databaseName = databaseNameP; 
     self.databaseLite = [self getNewDBConnection]; 
    } 
    return self; 
} 

- (void)createEditableCopyOfDatabaseIfNeeded { 
    NSLog(@"Creating editable copy of database"); 
    // First, test for existence. 
    BOOL success; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSError *error; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:self.databaseName]; 
    success = [fileManager fileExistsAtPath:writableDBPath]; 
    if (success) return; 
    // The writable database does not exist, so copy the default to the appropriate location. 
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:self.databaseName]; 
    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error]; 
    if (!success) { 
     NSAssert1(0, @"Failed to create writable database file with message ‘%@’.", [error localizedDescription]); 
    } 
} 

- (sqlite3 *) getNewDBConnection{ 
    sqlite3 *newDBconnection; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *path = [documentsDirectory stringByAppendingPathComponent:self.databaseName]; 
    // Open the database. The database was prepared outside the application. 
    if (sqlite3_open([path UTF8String], &newDBconnection) == SQLITE_OK) { 

     NSLog(@"Database Successfully Opened "); 

    } else { 
     NSLog(@"Error in opening database "); 
    } 

    return newDBconnection; 
} 

-(NSMutableArray *)getTestData:(NSInteger) testId{ 
    (NSMutableArray *testArray = [[NSMutableArray alloc]init]; 

    int ret; 
    sqlite3_stmt *selStmt = nil; 
    const char *sql = "SELECT testId, name, FROM TblTest WHERE testId = ?"; 

    if (!selStmt) 
    { // build update statement 
     if (sqlite3_prepare_v2(self.databaseLite, sql, -1, &selStmt, NULL)!=SQLITE_OK) 
     { 
      selStmt = nil; 
     } 
    } 

    sqlite3_bind_int(selStmt, 1, testId); 

    if(!selStmt){ 
     NSAssert1(0, @"Cant build SQL to read item [%s]", sqlite3_errmsg(self.databaseLite)); 
    } 

    while ((ret=sqlite3_step(selStmt))==SQLITE_ROW) 
    { // get the fields from the record set and assign to item 

     Test *test = [[Test alloc]init]; 

     NSNumber *testId = [NSNumber numberWithInt: (int) sqlite3_column_int(selStmt, 0)]; 
     NSString *name = [NSString stringWithUTF8String:(char *) sqlite3_column_text(selStmt, 1)]; 


     test.testId =testId; 
     test.name =name; 


     [testArray addObject:pill]; 
     [test release]; 
    } 
    sqlite3_reset(selStmt); 

    return [testArray autorelease]; 
} 



//in my function i do: 
qc = [[QueryClass alloc]initWithDatabase:@"databaseLite.sql"]; 
[qc getTestData:0]; 

我使用this教程改寫了我的代碼,它就像一個魅力。 :)

感謝

-(id)initWithDatabase:(NSString *)databaseNameP{ 
    if(self = [super init]){ 
     [self createEditableCopyOfDatabaseIfNeeded]; 
     [self initializeDatabase]; 
    } 
    return self; 
} 

// Creates a writable copy of the bundled default database in the application Documents directory. 
- (void)createEditableCopyOfDatabaseIfNeeded { 
    // First, test for existence. 
    BOOL success; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSError *error; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"databaseLite4.sqlite"]; 
    success = [fileManager fileExistsAtPath:writableDBPath]; 
    if (success) return; 
    // The writable database does not exist, so copy the default to the appropriate location. 
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"databaseLite4.sqlite"]; 
    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error]; 
    if (!success) { 
     NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]); 
    } 
} 

// Open the database connection and retrieve minimal information for all objects. 
- (void)initializeDatabase { 

    // The database is stored in the application bundle. 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    self.path = [documentsDirectory stringByAppendingPathComponent:@"databaseLite4.sqlite"]; 

} 
+0

「沒有這樣的表:TBLTEST」意味着表不存在於數據庫中。要麼你有一箇舊的數據庫,你需要先刪除應用程序,或者你拼錯了表名,或者你從來沒有創建過這樣的表。你有沒有檢查拼寫,也許它是tblTest或什麼? – vakio 2011-05-10 13:23:57

回答

1

當你解決你自己的問題,你應該提供您的解決方案作爲一個答案,而不是更新你的問題。這是可能的(並建議在這種情況下)回答你自己的問題,並接受它作爲你的答案。你不會因接受你自己的答案而獲得任何聲望,但問題將被正確列爲已解決。

下面是我從你的問題中提取的答案。隨時接受它。


我使用this教程改寫了我的代碼,它就像一個魅力。 :)

這裏是我的解決方案:

-(id)initWithDatabase:(NSString *)databaseNameP{ 
    if(self = [super init]){ 
     [self createEditableCopyOfDatabaseIfNeeded]; 
     [self initializeDatabase]; 
    } 
    return self; 
} 

// Creates a writable copy of the bundled default database in the application Documents directory. 
- (void)createEditableCopyOfDatabaseIfNeeded { 
    // First, test for existence. 
    BOOL success; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSError *error; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"databaseLite4.sqlite"]; 
    success = [fileManager fileExistsAtPath:writableDBPath]; 
    if (success) return; 
    // The writable database does not exist, so copy the default to the appropriate location. 
    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"databaseLite4.sqlite"]; 
    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error]; 
    if (!success) { 
     NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]); 
    } 
} 

// Open the database connection and retrieve minimal information for all objects. 
- (void)initializeDatabase { 

    // The database is stored in the application bundle. 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    self.path = [documentsDirectory stringByAppendingPathComponent:@"databaseLite4.sqlite"]; 

} 
+0

免費積分爲你;) – Oritm 2011-05-11 07:27:55