我在使用一个应用程序时遇到了问题,其中SQLite数据库被损坏了。此前偶尔出现这种情况,但自iOS 7.1发布后似乎变得更加普遍。
我正在使用由Matteo Bertozzi提供的SQLite包装器,您可以在此处找到:https://github.com/ConnorD/simple-sqlite
数据库会损坏并弹出错误database disk image is malformed
,有些查询可以运行,但现有数据会混乱。
我已经四处寻找解决方案,但没有找到,希望这里的某人有一些想法,因为这在iOS更新后变得更加普遍。
我尝试了以下修复命令:
[sqlite executeNonQuery:@"pragma integrity_check"];
[sqlite executeNonQuery:@"reindex nodes"];
[sqlite executeNonQuery:@"reindex pristine"];
输出结果为:
SQLite Step Failed: database disk image is malformed
SQLite Prepare Failed: unable to identify the object to be reindexed
- Query: reindex nodes
SQLite Prepare Failed: unable to identify the object to be reindexed
- Query: reindex pristine`
通过进一步的挖掘,我找到了这个问题:Core Data和iOS 7:持久存储的不同行为,其中提到在iOS7之后与SQLite相关的问题。
虽然我不知道如何使用NSPersistentStore
,所以我尝试运行[sqlite executeNonQuery:@"pragma journal_mode = DELETE"];
,但它只是显示了SQLite Step Failed: unknown error
。
还有其他人遇到过这个问题吗?或者可以指导我正确的方向吗?
与此同时,我觉得我可能应该使用NSPersistentStore
..需要研究一下。
编辑:
根据我的发现,当数据库不需要更新时才使用NSPersistentStore
,而我的数据库需要经常更新。
以下是我打开数据库的方式:
sqlite = [[Sqlite alloc] init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"HomeOpenDatabase8.sql"];
if (![sqlite open:writableDBPath]) {
NSLog(@"DB Not Writable");
return;
} else {
NSLog(@"All good");
}
所以我认为我需要找到一种方法来设置 pragma journal_mode = DELETE
这样做...?
编辑 2:
我并不认为这与journal_mode
有关,因为我没有使用Core Data
- 回到起点。
对我来说最大的标志是在iOS 7.1发布后很快就出现了这个错误,这肯定不是巧合...我会继续尝试在我的设备上复制这个问题。
journal_mode
的问题了,因为我没有使用Core Data
,所以又回到了原点。 - Batnomintegrity_check
等命令可能修复了数据损坏,而journal_mode
则是为了解决链接中描述的潜在Core Data
WAL
问题。 - Batnom