数据库升级(添加字段)_移动开发_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > 移动开发 > 数据库升级(添加字段)

数据库升级(添加字段)

 2017/4/27 5:32:07  放羊的王二小  程序员俱乐部  我要评论(0)
  • 摘要:本地做了一个浏览记录的缓存,在之前的版本中已经创建了一个对应的表,在新版本中对浏览记录进行了修改,所以得往已经存在的表中添加新的字段。最开始以为只要在创建表的地方添加上新的字段便大功告成了。NSString*sql=@"createtableSearchStatistics(idintegerprimarykeyautoincrement,searchUserAgentIdtext,searchUUIDtext,keywordtext)";[_dbexecuteUpdate:sql];运行之后
  • 标签:数据库 数据

 本地做了一个浏览记录的缓存,在之前的版本中已经创建了一个对应的表,在新版本中对浏览记录进行了修改,所以得往已经存在的表中添加新的字段。

  最开始以为只要在创建表的地方添加上新的字段便大功告成了。

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,最后更新表中字段。

class="cnblogs_code_copy">复制代码
#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文件中添加对应的字段,同时把数据库版本加一就行了。

  各位要是有更好的方法,互相分享一下哈。

发表评论
用户名: 匿名