在sqlite中的同一数据库中插入多个表

时间:2011-06-08 20:20:39

标签: iphone objective-c sqlite

创建Iphone应用程序,我曾经在不同的数据库上执行INSERT QUERY。 但是当我尝试在同一个数据库中插入数据时,它会让我断言失败。 我正在阅读两个不同的XML URL并尝试创建然后在创建数据库时读取数据。有谁知道为什么这会给我带来错误? 我有以下代码使用SQLITE在DB上插入:

  -(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 个答案:

答案 0 :(得分:1)

@lifemoveson

我习惯了你的代码来调试并找到了函数

sqlite3_prepare_v2(database, insert_product_sql, -1, &product_statement, nil)

每次都返回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的文档目录中。您可以在应用程序委托中调用此函数

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

}

当您进行任何数据库调用时,请使用此

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

我建议你为你执行的所有数据库操作编写一个单独的类,而是调用类函数来实现所需的功能。这将节省您重写代码的工作。

您可以使用FMDB包装器找到here

希望这会有所帮助: - )