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

标签 objective-c sqlite fmdb

我有一个大型 SQLite 文件,其中充满了用于创建数据库表并插入所有记录的查询。该文件相当大,并且运行 SQL 文件似乎花费的时间比我预期的要长得多。

我正在将 FMDB 用于我正在开发的 iPad 应用程序,并且我真的想用新的数据库文件替换当前的数据库文件,但我不确定 sql 文件与数据库文件是否相同。它不包含任何相同的 header 信息等...

执行此操作的最佳方法是什么?

最佳答案

如果做很多单独的UPDATEINSERT调用 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 历史上没有一个接口(interface)可以执行此操作(即使有一个 SQLite 函数 sqlite3_exec 正是可以执行此操作)。 extra 最近添加了一个内容名为 FMDatabaseSplitter 的文件夹,它尝试将一长串 SQL 拆分为单独的调用,然后您可以单独调用它们。

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

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]);
}

我必须承认,仅仅将批量 SQL 导入到应用程序的数据库中让我有点紧张。如果您不非常小心,SQL 中的一个无心错误可能会破坏整个安装库的应用程序。我宁愿看到应用程序从服务器请求 JSON 或 XML 提要,然后自行进行更新,但如果您想使用 .dump输出以使用 FMDB 更新应用程序的数据库,这是一种方法。


FMDB v2.3 引入了 sqlite3_exec 的包装器叫 executeStatements :

BOOL success;

NSString *sql = @"create table bulktest1 (id integer primary key autoincrement, x text);"
                 "create table bulktest2 (id integer primary key autoincrement, y text);"
                 "create table bulktest3 (id integer primary key autoincrement, z text);"
                 "insert into bulktest1 (x) values ('XXX');"
                 "insert into bulktest2 (y) values ('YYY');"
                 "insert into bulktest3 (z) values ('ZZZ');";

success = [db executeStatements:sql];

关于Objective-C - FMDB - 大型 SQLite 转储导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23065693/

相关文章:

objective-c - 在 objective-c 中获取颜色分量

android - 从 SQLite 数据库填充 ListView

ios FMDB 选择不在(?)

ios - UITableView 自己滚动

ios - 迪尔德 : dyld_sim not compatible mach-o

java - 如何根据日期列中的日期选择 SQLite 列

swift - 将任意长度的数组绑定(bind)到 SQLite 查询

IOS FMDB 良好实践

objective-c - 键盘不会用 UITextField 关闭

java - 我的 Action Bar 的 SearchView 如何在 ListView 上工作?