我有一个大的SQLite文件,里面装满了查询来创建我的数据库表并插入所有记录。该文件相当大,运行SQL文件似乎比我预期的要长得多。
我正在使用FMDB作为我正在处理的iPad应用程序,我真的想用新的DB文件替换当前的DB文件,但我不确定sql文件是否与DB文件相同。它不包含任何相同的标题信息等...
最好的方法是做什么?
答案 0 :(得分:4)
如果与UPDATE
进行了大量单独的INSERT
或FMDatabase
来电,请考虑在开始时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