2011-06-08 109 views
0

創建一個Iphone應用程序,我用來在不同的數據庫上執行INSERT QUERY。 但是,當我試圖在同一個數據庫中插入數據時,它會導致斷言失敗。 我正在閱讀兩個不同的XML URL,並試圖創建數據,然後將數據插入表中,因爲它是通過創建數據庫來讀取的。有沒有人知道爲什麼這會顯示我錯誤? 我有以下的代碼,並使用SQLite在DB插入:在sqlite的同一個數據庫中插入多個表

-(void) insertProductTable:(NSMutableArray *)Dict{ 
[Dict retain]; 
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *dbPath = [documentsDirectory stringByAppendingPathComponent:@"product.sql"]; 
NSInteger i; 

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

    const char * insert_product_sql = "INSERT OR REPLACE INTO test(ID,KEY) VALUES (?,?)" ; 
    if(sqlite3_prepare_v2(database, insert_product_sql, -1, &product_statement, nil) != SQLITE_OK){ 
     NSAssert1(0, @"Error: failed to prepare insert_product_sql: '%s'.", sqlite3_errmsg(database)); 
    } 

    for (i = 0; i < [self.array count]; i++) { 
    sqlite3_bind_text(product_statement, 1, [[Dict valueForKey:@"ID"] UTF8String] ,-1, SQLITE_TRANSIENT); 
    sqlite3_bind_text(product_statement, 2, [[Dict valueForKey:@"KEY"] UTF8String] ,-1, SQLITE_TRANSIENT); 
    } 

    if (sqlite3_step(product_statement) != SQLITE_DONE) { 
     NSAssert(0,@"Error updating table"); 
    } 

    [Dict release]; Dict = 0; 
    sqlite3_finalize(product_statement); 
    sqlite3_close(database); 

} 
} 

我有以下的方法,做不同的插入功能,但不同的表,但在這個階段,不列入允許我插入扔我斷言失敗。這兩種方法都由不同的類來調用。

-(void) insertTable:(NSMutableArray *)Dict{ 
[Dict retain]; 
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *dbPath = [documentsDirectory stringByAppendingPathComponent:@"product.sql"]; 
NSInteger i; 

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

    const char * insert_sql = "INSERT OR REPLACE INTO test1(Term,Value) VALUES (?,?)" ; 
    if(sqlite3_prepare_v2(database, insert_sql, -1, &product_statement, nil) != SQLITE_OK){ 
     NSAssert1(0, @"Error: failed to prepare insert_sql: '%s'.", sqlite3_errmsg(database)); 
    } 

    for (i = 0; i < [self.arayList count]; i++) { 
    sqlite3_bind_text(product_statement, 1, [[Dict valueForKey:@"TERM"] UTF8String] ,-1, SQLITE_TRANSIENT); 
    sqlite3_bind_text(product_statement, 2, [[Dict valueForKey:@"VALUE"] UTF8String] ,-1, SQLITE_TRANSIENT); 
    } 

    if (sqlite3_step(product_statement) != SQLITE_DONE) { 
     NSAssert(0,@"Error updating table"); 
    } 

    [Dict release]; Dict = 0; 

    sqlite3_finalize(product_statement); 
    sqlite3_close(database); 

} 
} 

回答

1

@lifemoveson

我用你的代碼調試和發現功能

​​

返回1次,每次和它在所需位置對應於你丟失的數據庫。

我會建議你是做一個函數,如本

-(void)checkAndCreateDatabase{ 
    databaseName = @"MasterDB.sqlite"; 
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDir = [documentPaths objectAtIndex:0]; 
    databasePath = [documentsDir stringByAppendingPathComponent:databaseName]; 
    NSLog(@"database path %@",databasePath); 
    BOOL success; 

    // Create a FileManager object, we will use this to check the status 
    // of the database and to copy it over if required 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 

    // Check if the database has already been created in the users filesystem 
    success = [fileManager fileExistsAtPath:databasePath]; 

    // If the database already exists then return without doing anything 
    if(success) return; 

    // If not then proceed to copy the database from the application to the users filesystem 

    // Get the path to the database in the application package 
    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName]; 

    // Copy the database from the package to the users filesystem 
    [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil]; 
    //[fileManager release]; 

    // Now we can add new table 

    sqlite3 *database; 
    sqlite3_stmt *statement; 
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) 
    { 

     NSString *sqlQuery = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS tbl_Login (userId integer PRIMARY KEY,userName text,password text);"] ; 
     const char *create_stmt = [sqlQuery UTF8String]; 
     sqlite3_prepare_v2(database, create_stmt, -1, &statement, NULL); 

     if(sqlite3_step(statement)==SQLITE_DONE) 
     { 
      NSLog(@"Table created");    
     } 
     else 
     { 
      NSLog(@"Table could not be created"); 
     } 
     // Release the compiled statement from memory 
     sqlite3_finalize(statement);  
     sqlite3_close(database); 
    } 
} 

它設置你的類變量databasePath並確保運行的任何數據庫查詢數據庫中的applcation的文檔目錄實際存在之前。當你進行任何數據庫調用使用該

const char *dbpath = [databasePath UTF8String]; 
    if (sqlite3_open(dbpath , &database) == SQLITE_OK) { 
//Code to perform insert operations 
} 

我建議你寫一個單獨的類爲您執行,而是調用所有數據庫操作可以調用應用程序委託

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ 
//Other code 
[self checkAndCreateDatabase]; 

} 

此功能類功能來實現所需的功能。這樣可以節省你重寫代碼的工作量。

您可以使用FMDB包裝的這個,你可以找到here

希望這有助於:-)

+0

感謝拉胡爾的指點錯誤和解決方案。還有一個小問題。如何在checkAndCreateDatabase中添加Create table查詢或是否需要爲create查詢添加新函數?另外,我在不同的類中有兩個不同的函數可以在同一個數據庫中執行兩個插入查詢。我怎樣才能做到這一點? – lifemoveson 2011-06-09 05:38:31

+0

我已經更新了我原來的答案。希望它有幫助 – 2011-06-09 06:36:59

+0

感謝Rahul的幫助。我確實使用了你所建議的邏輯,但有一個快速的問題。正如你所看到的,我在不同的類中有兩個不同的插入函數。如何將數據庫指向該目錄?此外,我之前並沒有使用過FMDB,也不知道它是如何工作的。我不確定我是否會使用它。 – lifemoveson 2011-06-09 14:50:26

相關問題