批量插入到Sqlite3导致Db错误:库例程被调用不按顺序

时间:2010-08-12 06:25:17

标签: iphone objective-c multithreading sqlite

我需要在我的iphone应用更新应用后加载一些配置数据。我在一个文件中捆绑了一堆SQL语句(800+),以便在首次启动时运行。看起来我现在可能被涂在角落里了。如果我在启动时在主线程上运行它,那么由于启动时间太长而导致应用程序崩溃需要很长时间。如果我在一个单独的线程上运行它,我将收到数据库争用错误(库例程被称为不按顺序)。我认为这是因为应用程序继续在主线程上加载和读取数据库。

以下是从CSV文件接收数据然后循环并写入数据库的方法。

有关如何在启动时更快运行或在低优先级后台线程上没有争用而成功运行的任何想法?

+ (void) updateDB:(NSString *)data {
    NSArray  *lineArray = [data componentsSeparatedByString:@"\n"];
    if (sqlite3_open([[BIUtility getDBPath] UTF8String], &database) != SQLITE_OK) {
        sqlite3_close(database);
        NSLog(@"Failed to opendatabase in updateDB");
    }
    char *errorMsg;

    for(int k = 0; k < [lineArray count]; k++){
        NSString *loadSQLi = [lineArray objectAtIndex:k];

        if (sqlite3_exec(database, [loadSQLi UTF8String], NULL, NULL, &errorMsg) != SQLITE_OK) {
            NSLog(@"DB Error. '%s'", sqlite3_errmsg(database));
        }

    }

    if(database) sqlite3_close(database);

}

2 个答案:

答案 0 :(得分:0)

您可以通过在单个事务中执行所有插入而不是在单独的事务中执行插入来更快地执行此操作,因为默认情况下会在该代码中执行此操作。

答案 1 :(得分:0)

+ (void) updateDB:(NSString *)data {
    NSArray  *lineArray = [data componentsSeparatedByString:@"\n"];
    if (sqlite3_open([[BIUtility getDBPath] UTF8String], &database) != SQLITE_OK) {
        sqlite3_close(database);
        NSLog(@"Failed to opendatabase in updateDB");
    }
    char *errorMsg;

    execQuery(@"Begin Transaction");

    for(int k = 0; k < [lineArray count]; k++){
        NSString *loadSQLi = [lineArray objectAtIndex:k];
        execQuery(loadSQLi);
    }

    execQuery(@"Commit");

    if(database) sqlite3_close(database);

}

+ (void) execQuery:(NSString *)query {
    char *errorMsg;
    if (sqlite3_exec(database, [query UTF8String], NULL, NULL, &errorMsg) != SQLITE_OK) {
        NSLog(@"DB Error. '%s'", sqlite3_errmsg(database));
    }
}