BUG是这样的:有默认数据的表有时添加数据不成功,错误提示如下
CoreData: error: (19) constraint failed
Core Data: annotation: -executeRequest: encountered exception = error during SQL execution : constraint failed with userInfo = {
NSFilePath = "filePath.sqlite";
NSSQLiteErrorDomain = 19;
}
复制代码开发过程中更改过数据结构,最终的默认数据库是用CSV导入并且只导入了有默认数据的表;BUG原因应该是默认数据库缺少某个添加记录时需要的值。
一.core data自动声称的表和属性
Z_PRIMARYKEY
1.Z_ENT --实体ID
2.Z_NAME
3.Z_SUPER
4.Z_MAX --实体所用到的最大ID(关键所在)
自定义表中的属性
1.Z_PK -- 对象的唯一ID
2.Z_ENT -- 实体ID 跟Z_PRIMARYKEY表中的值一样
3.Z_OPT -- 编辑次数
重点自然是Z_MAX和Z_PK
Z_PK是一个对象的"唯一"ID,正常的添加过程大概是这样的:
NEW_PK = ++Z_MAX;
insert();
复制代码
不管表中记录是否已经删除,Z_MAX都只会+1,不会变小,以此保证ID的唯一性。
默认数据库里没有更改Z_PRIMARYKEY表中的值,Z_MAX都是默认的0,添加不上是因为Z_MAX的值不符合规则。
真实的添加过程大概的是这样的:
if ((Z_MAX += 4) < max(Z_PK)) { //不知道为什么是4
constrain_failed();
} else {
NEW_PK = Z_MAX = max(Z_PK) + 1;
insert();
}
复制代码比如说默认数据库里有10条记录,前两次添加操作都是不成功的;第三次添加成功并且Z_MAX也会成为正确的值:11。
二.修正
修改默认数据库只能使新用户的体验正常,对于已经下载的用户就没有效果了,所以需要更新用户的数据库。
目前想到的方法是在用户进入应用的时候调用sqlite的API UPDATE一下:
char *update = "UPDATE Z_PRIMARYKEY SET Z_MAX = (select max(Z_PK) from ZTHETABLE) WHERE (Z_NAME = myTableName)";
sqlite3_exec(database, update, NULL, NULL, NULL);
CoreData: error: (19) constraint failed
Core Data: annotation: -executeRequest: encountered exception = error during SQL execution : constraint failed with userInfo = {
NSFilePath = "filePath.sqlite";
NSSQLiteErrorDomain = 19;
}
复制代码开发过程中更改过数据结构,最终的默认数据库是用CSV导入并且只导入了有默认数据的表;BUG原因应该是默认数据库缺少某个添加记录时需要的值。
一.core data自动声称的表和属性
Z_PRIMARYKEY
1.Z_ENT --实体ID
2.Z_NAME
3.Z_SUPER
4.Z_MAX --实体所用到的最大ID(关键所在)
自定义表中的属性
1.Z_PK -- 对象的唯一ID
2.Z_ENT -- 实体ID 跟Z_PRIMARYKEY表中的值一样
3.Z_OPT -- 编辑次数
重点自然是Z_MAX和Z_PK
Z_PK是一个对象的"唯一"ID,正常的添加过程大概是这样的:
NEW_PK = ++Z_MAX;
insert();
复制代码
不管表中记录是否已经删除,Z_MAX都只会+1,不会变小,以此保证ID的唯一性。
默认数据库里没有更改Z_PRIMARYKEY表中的值,Z_MAX都是默认的0,添加不上是因为Z_MAX的值不符合规则。
真实的添加过程大概的是这样的:
if ((Z_MAX += 4) < max(Z_PK)) { //不知道为什么是4
constrain_failed();
} else {
NEW_PK = Z_MAX = max(Z_PK) + 1;
insert();
}
复制代码比如说默认数据库里有10条记录,前两次添加操作都是不成功的;第三次添加成功并且Z_MAX也会成为正确的值:11。
二.修正
修改默认数据库只能使新用户的体验正常,对于已经下载的用户就没有效果了,所以需要更新用户的数据库。
目前想到的方法是在用户进入应用的时候调用sqlite的API UPDATE一下:
char *update = "UPDATE Z_PRIMARYKEY SET Z_MAX = (select max(Z_PK) from ZTHETABLE) WHERE (Z_NAME = myTableName)";
sqlite3_exec(database, update, NULL, NULL, NULL);