本地做了一個浏覽記錄的緩存,在之前的版本中已經創建了一個對應的表,在新版本中對浏覽記錄進行了修改,所以得往已經存在的表中添加新的字段。
最開始以為只要在創建表的地方添加上新的字段便大功告成了。
NSString *sql = @"create table SearchStatistics (id integer primary key autoincrement, searchUserAgentId text, searchUUID text, keyword text)"; [_db executeUpdate:sql];
運行之後,發現添加的字段並沒有生效,後來查看日志,發現新加的字段在插入的時候居然在表中找不到。
後來想了一下,因為之前本地這個表已經被創建了所以這個方法不會走了,於是便想到往已有的表中添加字段。
NSString *sql = @"alter table ReplaceSellList add keyword text"; [self.db executeUpdate:sql]
但是這樣的話又會有一個問題,要是以後的版本還會要添加字段的話,那我勢必寫很多的sql來添加字段。於是乎想了一個辦法,在本地創建一個 plist文件用來保存新增的字段,每次更新取表中的字段和plist文件中的字段作對比,取出新的字段生成對應的sql,最後更新表中字段。
#pragma mark 檢查是否更新表字段 - (void)checkUpdateSearchTable { if ([self.db open]) { if ([self.db tableExists:@"SearchStatistics"]) { NSInteger lastVersion = [[[NSUserDefaults standardUserDefaults] objectForKey:SearchOldSqliteVersionKey] integerValue]; if (lastVersion < CURRENTSQLVERSION) { [self updateSearchTable]; } } [self.db close]; } } #pragma mark 更新表字段 - (void)updateSearchTable { NSString *path = [[NSBundle mainBundle] pathForResource:@"SearchStaticsField" ofType:@"plist"]; NSDictionary *newFiledDic = [[NSDictionary alloc]initWithContentsOfFile:path]; NSArray *allField = [self getColumnArr:@"SearchStatistics" db:self.db]; NSArray *newFilds = [self compareKeys:[newFiledDic allKeys] tableNames:allField]; //對比老表,獲取需要更新的新字段 if (newFilds.count) { NSMutableArray *sqls = [[NSMutableArray alloc]init]; for (NSString *key in newFilds) { NSString *type = newFiledDic[key]; [sqls addObject:[NSString stringWithFormat:@"alter table SearchStatistics add %@ %@",key,type]]; } //事務提交,更新表 [self.db beginTransaction]; // 調用之前打開db BOOL isRollBack = NO; @try { for (int i = 0; i < sqls.count; i++) { NSString *sql = sqls[i]; BOOL b = [self.db executeUpdate:sql]; if (!b) { NSLog(@"第%d條sql語句執行失敗", i); } } } @catch (NSException *exception) { isRollBack = YES; [self.db rollback]; } @finally { if (!isRollBack) { if ([self.db commit]) { [[NSUserDefaults standardUserDefaults] setInteger:CURRENTSQLVERSION forKey:SearchOldSqliteVersionKey]; } } } } [self.db close]; } #pragma mark 獲取表中所有字段 - (NSArray *)getColumnArr:(NSString *)tableName db:(FMDatabase *)db { NSMutableArray *mArr = [NSMutableArray arrayWithCapacity:0]; if ([self.db open]) { FMResultSet *resultSet = [db getTableSchema:tableName]; while ([resultSet next]) { [mArr addObject:[resultSet stringForColumn:@"name"]]; } } return mArr; } - (NSArray *)compareKeys:(NSArray *)keys tableNames:(NSArray *)tKeys { NSPredicate * filterPredicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)",tKeys]; //過濾數組 NSArray * reslutFilteredArray = [keys filteredArrayUsingPredicate:filterPredicate]; return reslutFilteredArray; }
這樣,每次有新的字段加入,只需要往plist文件中添加對應的字段,同時把數據庫版本加一就行了。
各位要是有更好的方法,互相分享一下哈。