我有一個龐大的SQLite文件填滿了查詢來創建我的數據庫表並插入所有記錄。該文件相當大,運行SQL文件似乎比我預期的要長得多。Objective-C - FMDB - 大型SQLite轉儲導入
我正在爲我正在使用的一個iPad應用程序使用FMDB,而且我真的只想用一個新的數據庫替換當前的數據庫文件,但我不確定sql文件是否與數據庫文件相同。它不包含任何相同的標題信息,等等......
什麼是最好的方式去做到這一點?
我有一個龐大的SQLite文件填滿了查詢來創建我的數據庫表並插入所有記錄。該文件相當大,運行SQL文件似乎比我預期的要長得多。Objective-C - FMDB - 大型SQLite轉儲導入
我正在爲我正在使用的一個iPad應用程序使用FMDB,而且我真的只想用一個新的數據庫替換當前的數據庫文件,但我不確定sql文件是否與數據庫文件相同。它不包含任何相同的標題信息,等等......
什麼是最好的方式去做到這一點?
如果做了很多單獨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
文件夾最近增加了一個名爲FMDatabaseSplitter
的文件夾,該文件夾試圖將一長串SQL分割成單獨的調用,然後您可以單獨調用它們。
個人而言,它使我很緊張地使用第三方SQL解析例程,所以我只是傾向於直接調用SQLite函數sqlite3_exec
。要做到這一點,你可以使用FMDB sqliteHandle
方法從FMDatabase
對象訪問sqlite3
指針,然後使用結合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提要,然後自己進行更新,但是如果您想使用輸出來更新應用程序的FMDB數據庫,那麼這是一種方法。
FMDB V2.3已經推出了一個名爲executeStatements
爲sqlite3_exec
的包裝:
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];
這是一些非常好的建議......但是我怎麼會做這樣一個大的SQL文件? – rckehoe
我確實使用JSON最初請求所有數據,問題在於它需要很長時間才能打開。所以我不得不想一個不同的方式。 – rckehoe
@rckehoe夠公平的。如果SQL文件小得多,我會感到驚訝。我不知道在傳輸時間內有多少性能問題是真的,有多少問題是沒有事務(如果通過SQL執行'BEGIN TRANSACTION'和'COMMIT',如果使用了'beginTransaction'和'commit' FMDB接口)。看到在更新過程中通過使用事務可以實現多少性能改進,這確實令人驚訝。我是一個實用主義者,所以如果使用SQL文件有幫助,那很好,但如果真的是這個問題,我會感到驚訝。 – Rob