Objective-C - FMDB - 大型SQLite转储导入

时间:2014-04-14 16:47:25

标签: objective-c sqlite fmdb

我有一个大的SQLite文件,里面装满了查询来创建我的数据库表并插入所有记录。该文件相当大,运行SQL文件似乎比我预期的要长得多。

我正在使用FMDB作为我正在处理的iPad应用程序,我真的想用新的DB文件替换当前的DB文件,但我不确定sql文件是否与DB文件相同。它不包含任何相同的标题信息等...

最好的方法是做什么?

1 个答案:

答案 0 :(得分:4)

如果与UPDATE进行了大量单独的INSERTFMDatabase来电,请考虑在开始时beginTransaction和最后commit

[db beginTransaction];
// do all of your updates
[db commit];

或者,如果使用FMDatabaseQueue,请使用inTransaction

[databaseQueue inTransaction:^(FMDatabase *db , BOOL *rollback) { 
    // do all of your updates
}];

如果你不使用其中一个,它会在每次插入后提交,这会使它慢得多。如果添加大量行,差异可能会很大(例如,在添加/更新大量小记录时,我已经看到两个数量级的性能差异)。


以上假设您尝试执行一系列单独的SQL命令。如果它全部在一个文件中(例如.dump输出),则FMDB历史上没有一个接口来执行该操作(即使有一个SQLite函数,sqlite3_exec,确实如此)。最近添加了名为extra的{​​{1}}文件夹,它试图将一长串SQL拆分为单独的调用,然后您可以单独调用它们。

就个人而言,使用第三方SQL解析例程让我感到紧张,所以我只是倾向于直接调用SQLite函数sqlite3_exec。为此,您可以使用FMDB FMDatabaseSplitter方法从sqlite3对象访问FMDatabase指针,然后将其与sqliteHandle函数直接结合使用:

sqlite3_exec

我必须承认,只是将批量SQL导入到应用程序的数据库中会让我有点紧张。如果您不是非常小心的话,SQL中的无辜错误可能会破坏整个安装基础的应用程序。我宁愿看到应用程序从服务器请求JSON或XML提要,然后自己进行更新,但是如果要使用NSError *error = nil; NSString *dumpSQL = [NSString stringWithContentsOfFile:dumpFilePath encoding:NSUTF8StringEncoding error:&error]; NSAssert(dumpSQL, @"Loading of SQL failed: %@", error); int rc = sqlite3_exec(db.sqliteHandle, [dumpSQL UTF8String], NULL, NULL, NULL); if (rc != SQLITE_OK) { NSLog(@"sqlite3_exec error: %@", [db lastErrorMessage]); } 输出来使用FMDB更新应用程序的数据库,这是一种方法。


FMDB v2.3引入了名为executeStatements.dump包装器:

sqlite3_exec