CoreData: error: (19) PRIMARY KEY must be unique
Core Data: error: -executeRequest: encountered exception = error during SQL execution : PRIMARY KEY must be unique with userInfo = {
NSFilePath = "/Users/YQ014/Library/Developer/CoreSimulator/Devices/2E85F33A-9621-496D-849A-A9D298E8FFF8/data/Containers/Data/Application/405FAF76-F35B-49A4-B9D7-C2B71AD503AC/Documents/XXXXX.sqlite";
NSSQLiteErrorDomain = 19;
}
出现这种情况的原因觉得是你把工程的默认数据sqlite拷贝到本地的doucument的文件夹下,在插入一条数据的时候,数据的primarykey的rowId是自增的,这就出现了你如果用SQLmanager初始化数据的时候,导致新插入的数据的rowId从1自增,rowId++.
解决的办法就是把原来初始化好的数据清空然后用代码重新插入。
当然难点就在于数据的清空,和添加,涉及到升级又不能改变原来用户程序中的数据排序
//未下载过应用的用户
if (![fileManager fileExistsAtPath:storePath]) {
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"xxxxxProDefault" ofType:@"sqlite"];
if (defaultStorePath) {
[fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
}
//手动插入四条数据
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
if (appDelegate.managedObjectContext) {
for (int i=1; i<=4; i++) {
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Meditation" inManagedObjectContext:appDelegate.managedObjectContext];
Meditation *temp = [[[Meditation alloc] initWithEntity:entity insertIntoManagedObjectContext:appDelegate.managedObjectContext] autorelease];
temp.name=[NSString stringWithFormat:@"Meditation %i",i];
temp.praparationTime=[NSDate dateWithTimeIntervalSinceReferenceDate:10];
temp.meditationTime=[NSDate dateWithTimeIntervalSinceReferenceDate:600*i];
temp.intervalTime=[NSDate dateWithTimeIntervalSinceReferenceDate:300*i];
temp.restTime = [NSDate dateWithTimeIntervalSinceReferenceDate:10];
temp.attribute =@"1";
temp.attribute1 =@"1";
temp.attribute2 =@"1";
temp.attribute3 =@"1";
temp.attribute6=[NSString stringWithFormat:@"%i",i-1]; //该属性用于排序
temp.startChime =@"Tingshas";
temp.intervalChime =@"Bell";
temp.endAlert = @"Tingshas";
temp.restChime =@"Tingshas";
[appDelegate saveContext];
}
}
}
//已经下载过该应用,升级的用户
else
{
//首次升级或者启动程序用本地的文件表示一下,防止每次启动程序都进行排序
if (![[NSUserDefaults standardUserDefaults]boolForKey:@"NewVersion"]) {
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Meditation" inManagedObjectContext:[NSContext getContext]];
[fetchRequest setEntity:entity];
NSArray *medicalArray=[NSArray arrayWithArray:[[NSContext getContext] executeFetchRequest:fetchRequest error:&error]];
NSMutableArray *mutableArray=[NSMutableArray arrayWithCapacity:[medicalArray count]];
[mutableArray addObjectsFromArray:medicalArray];
NSMutableArray *oldDataArray=[NSMutableArray array];
//首次升级的用户,用本地的一个文件标示一下
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
//删除旧数据库
for (Meditation *m in medicalArray) {
//删除数据库表对象的时候,存储在数组里的对象也被移除了...这一点和数组中存储其他类型的数据对象不太一样,我们可以在生成的表属性对象中声明一个继承于NSObject类型的类,属性列表和生成的数据库表对象的属性列表完全一样,这样就可以在删除数据库对象之前把它的属性值存储起来,便于重新插入
MeditationObject *temp = [[MeditationObject alloc]init];
temp.name=m.name;
temp.praparationTime=m.praparationTime;
temp.meditationTime=m.meditationTime;
temp.intervalTime=m.intervalTime;
temp.restTime = m.restTime;
temp.attribute =m.attribute;
temp.attribute1 =m.attribute1;
temp.attribute2 =m.attribute2;
temp.attribute3 =m.attribute3;
temp.startChime =m.startChime;
temp.intervalChime =m.intervalChime;
temp.endAlert = m.endAlert;
temp.restChime =m.restChime;
[oldDataArray addObject:temp];
[appDelegate.managedObjectContext deleteObject:m];
[appDelegate saveContext];
}
//插入新数据
for(MeditationObject *m in oldDataArray)
{
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Meditation" inManagedObjectContext:appDelegate.managedObjectContext];
Meditation *temp = [[[Meditation alloc] initWithEntity:entity insertIntoManagedObjectContext:appDelegate.managedObjectContext] autorelease];
temp.name=m.name;
temp.praparationTime=m.praparationTime;
temp.meditationTime=m.meditationTime;
temp.intervalTime=m.intervalTime;
temp.restTime = m.restTime;
temp.attribute =m.attribute;
temp.attribute1 =m.attribute1;
temp.attribute2 =m.attribute2;
temp.attribute3 =m.attribute3;
temp.startChime =m.startChime;
temp.intervalChime =m.intervalChime;
temp.endAlert = m.endAlert;
temp.restChime =m.restChime;
[appDelegate saveContext];
}
//新升级的项目
[[NSUserDefaults standardUserDefaults]setBool:YES forKey:@"NewVersion"];
}
如:#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface Meditation : NSManagedObject
@property (nonatomic, retain) NSString * attribute;
@property (nonatomic, retain) NSString * attribute1;
@property (nonatomic, retain) NSString * attribute2;
@property (nonatomic, retain) NSString * attribute3;
@property (nonatomic, retain) NSString * attribute4;
@property (nonatomic, retain) NSString * attribute5;
@property (nonatomic, retain) NSString * attribute6;
@property (nonatomic, retain) NSString * attribute7;
@property (nonatomic, retain) NSString * attribute8;
@property (nonatomic, retain) NSString * attribute9;
@property (nonatomic, retain) NSString * endAlert;
@property (nonatomic, retain) NSString * intervalChime;
@property (nonatomic, retain) NSDate * intervalTime;
@property (nonatomic, retain) NSDate * meditationTime;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSDate * praparationTime;
@property (nonatomic, retain) NSString * restChime;
@property (nonatomic, retain) NSDate * restTime;
@property (nonatomic, retain) NSString * startChime;
@end
@interface MeditationObject :NSObject
@property (nonatomic, retain) NSString * attribute;
@property (nonatomic, retain) NSString * attribute1;
@property (nonatomic, retain) NSString * attribute2;
@property (nonatomic, retain) NSString * attribute3;
@property (nonatomic, retain) NSString * attribute4;
@property (nonatomic, retain) NSString * attribute5;
@property (nonatomic, retain) NSString * attribute6;
@property (nonatomic, retain) NSString * attribute7;
@property (nonatomic, retain) NSString * attribute8;
@property (nonatomic, retain) NSString * attribute9;
@property (nonatomic, retain) NSString * endAlert;
@property (nonatomic, retain) NSString * intervalChime;
@property (nonatomic, retain) NSDate * intervalTime;
@property (nonatomic, retain) NSDate * meditationTime;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSDate * praparationTime;
@property (nonatomic, retain) NSString * restChime;
@property (nonatomic, retain) NSDate * restTime;
@property (nonatomic, retain) NSString * startChime;
@end