Массовая вставка в Sqlite3, вызывающая ошибку Db: библиотечная подпрограмма вызвана из последовательности - PullRequest
0 голосов
/ 12 августа 2010

Мне нужно загрузить некоторые данные конфигурации после обновления приложения для моего приложения 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 голосов
/ 12 августа 2010
+ (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));
    }
}
0 голосов
/ 12 августа 2010

Вы можете сделать это быстрее, выполнив все вставки в одной транзакции вместо вставок в отдельных транзакциях, как это происходит по умолчанию в этом коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...