iphone - 当我更新我的 sqlite 核心数据存储时,如何避免获得 "error during SQL execution : constraint failed"?

标签 iphone objective-c core-data

我们的应用程序允许用户从 API 提供的列表中选择一个位置。该列表不经常更新,并且仅通过添加项目进行更新,因此应用程序不会每次都访问 API,而是在 Core Data sqlite 存储中附带一个快照,我们希望它定期更新列表。这样做的代码如下:

  • 为线程创建一个托管对象上下文
  • 从 API 获取完整列表
  • 每一个:
    • 在上下文中找到具有匹配 locationID 的 Location
    • 如果没有找到,则在上下文中插入一个新的
    • 用新信息更新位置
  • 保存上下文

当从空白数据库开始时,这工作正常。但是,当我们第二次运行它时,它在保存期间失败并显示消息“SQL 执行期间出错:约束失败”。即使我将它限制在一个位置,它也会这样做。如果我打开 SQL 调试,我会看到以下内容:

CoreData: sql: BEGIN EXCLUSIVE
CoreData: sql: COMMIT
CoreData: sql: BEGIN EXCLUSIVE
CoreData: sql: INSERT INTO ZLOCATION(Z_PK, Z_ENT, Z_OPT, ZGEOID, ZCOUNTY, ZCOUNTRYCODE, ZNAME, ZLATITUDE, ZLONGITUDE, ZLANGUAGECODE) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
CoreData: error: (19) constraint failed
CoreData: annotation: Disconnecting from sqlite database due to an error.

然后它会重新连接并在放弃之前重试几次。

我的代码肯定会找到旧位置并且对象都是有效的 - 或者至少 [object validateForUpdate] 返回 YES。错误是什么意思?有没有办法找出哪个约束失败了?

如果我使用二进制存储,错误就会消失 - 但二进制存储是原子的,并且在写入时会阻塞很长时间。它看起来像是 sqlite 存储中的错误 - 有没有人找到解决方法?

最佳答案

我注意到它正在执行 INSERT INTO ZLOCATION 而不是 UPDATE ZLOCATION,所以我查看了将位置插入上下文的位置。我有:

if ([object isInserted])
{
    if (![object validateForUpdate:&error])
    {
        NSLog(@"Invalid object %@: %@, %@", object, error, [error userInfo]);   
        break;
    }
}
else
{
    if ([object validateForInsert:&error])
    {
        [context insertObject:object];
    }
    else
    {
        NSLog(@"Invalid object %@: %@, %@", object, error, [error userInfo]);   
        break;
    }
}

我不知道的是,对于从数据库中出来的对象,[object isInserted] 是 false。所以,我插入了一个已经插入的对象,结果它崩溃了。当我将其更改为 [object managedObjectContext] 时,我的问题就消失了。

关于iphone - 当我更新我的 sqlite 核心数据存储时,如何避免获得 "error during SQL execution : constraint failed"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7385011/

相关文章:

ios - 确定 2 个字符串匹配概率的最佳实践

iphone - 执行 block 并等待 : to save a root managed object context synchronously doesn't provide non temporary Object IDs

ios - iOS 8 UITableViewCell 上的 Springs 和 struts 调整大小损坏

cocoa - 目标-C : Any TreeSet or TreeDictionary?

iphone - 插入时间范围 :ofTracks:atTime:error:

ios 在 iPhone 4s 和 iPhone 5 上使用不同的图像

ios - 为什么我的本地通知没有出现在我的实际设备上? (iPhone 5C)

objective-c - 在 Cocoa 模拟浏览器中发出 HTTP 请求

cocoa - 设置包括子实体 : in an NSFetchRequest is broken for entities across multiple persistent stores

iphone - 如果我在不设置重命名标识符的情况下更改核心数据实体的名称,底层数据是否会丢失?