美文网首页
FMDB 根据表名获取对应的列名是否存在

FMDB 根据表名获取对应的列名是否存在

作者: Raybon_lee | 来源:发表于2016-03-02 11:15 被阅读3139次

    为什么要写这个简单的文章:

    1. 我的表已经创建好了,而我又执行了一个 增加列字段的操作,所以这个是更新数据库需要的,按道理来说应当检测一下字段是否存在。
    2. 更新字段脚本我们更新过一次就不能执行第二次了,随不起眼,但是会影响数据库操作。
    3. 所以执行自动更新字段的操作前我们还是有必要先预判一下该字段是否存在,然后在进行是否执行更新操作,这个相对来说更合理一些。

    咨询了一部分人,都说是,根据表名进行字段模糊查询,经过测试之后,发现并不是很如意,我就查了一些FMDB里面的代码 确实有一些方法是可以间接获取对应的Key值的。

    更新表中的某个字段sql 语句(省的小伙伴再找了)
    ALTER TABLE table_name ADD 列名 TEXT
    我们先看下FMDB的源码获取Key 的部分

    - (void)setupColumnNames {
        
        if (!_columnNameToIndexMap) {
            [self setColumnNameToIndexMap:[NSMutableDictionary dictionary]];
        }    
        
        int columnCount = sqlite3_column_count([_statement statement]);
        
        int columnIdx = 0;
        for (columnIdx = 0; columnIdx < columnCount; columnIdx++) {
            [_columnNameToIndexMap setObject:[NSNumber numberWithInt:columnIdx]
                                     forKey:[[NSString stringWithUTF8String:sqlite3_column_name([_statement statement], columnIdx)] lowercaseString]];
        }
        _columnNamesSetup = YES;
    }
    
    

    上面这个方法是私有方法,外部是不允许直接调用的,或者在增加一外部API接口。
    这里我选择了另外一种方法

    - (int)columnIndexForName:(NSString*)columnName {
        
        if (!_columnNamesSetup) {
            [self setupColumnNames];
        }
        
        columnName = [columnName lowercaseString];
        
        NSNumber *n = [_columnNameToIndexMap objectForKey:columnName];
        
        if (n) {
            return [n intValue];
        }
        
        NSLog(@"Warning: I could not find the column named '%@'.", columnName);
        
        return -1;
    }
    

    这个方法是传入一个你要检测的字段名字,查询获取到对应的index 索引。
    如果有这个字段,会返回对应的索引,否则返回 -1 .

    -1: 这个神圣的数字代表什么呢,看到log 了么,查询不到当前的字段
    如果
    非-1: 该字段存在,得到想要的结果了,

    具体查询查询实现代码如下:

    - (BOOL)selectHardTableColums{
       
        [_db open];
        NSString * sqlstr = [NSString stringWithFormat:@"select * from %@",HardSynTable_Record];
        FMResultSet * result = [_db executeQuery:sqlstr];
        [result columnIndexForName:SYNC_ALBUM_MUSIC_COUNT];
        
        NSLog(@"result = %@",result);
    //    for (int i=0; i<[result columnCount]; i++) {
    //        NSString * columnName = [result columnNameForIndex:i];
    //        if ([columnName containsString:SYNC_ALBUM_MUSIC_COUNT]) {
    //            return YES;
    //        }
    //    }
        NSDictionary * dict =   [result columnNameToIndexMap];
        if (dict) {
            for (NSString * keystr in [dict allKeys]) {
                if ([keystr containsString:SYNC_ALBUM_MUSIC_COUNT]) {
                    return YES;
                }
            }
        }
        
       
        return NO;
        
    }
    
    

    columnIndexForName 你们是不是看到我这个地方了,为什么先调用这个方法。
    一开始我调用的是 [result columnNameToIndexMap] 这个方法是返回一个带有索引的字典 key-value 形式的,刚开始直接调用一直返回nil 我没注意,进去我看了一些没有调用到 setupcolumnnames 方法,所以优先调用 columnIndexForName方法,进行setup 字典初始化一次。

    上面我们说了两种方法

    1. 这是其中一种方法,前提是我们调用了[result columnNameToIndexMap]
    if (dict) {
            for (NSString * keystr in [dict allKeys]) {
                if ([keystr containsString:SYNC_ALBUM_MUSIC_COUNT]) {
                    return YES;
                }
            }
        }
    
    1. 另外一种方法 FMDB提供了一个columnCount 的方法,返回一个列的数量 columnNameForIndex:i 这个方法可以根据索引查找每个列下的列名,在这进行了一个遍历是比较安全的,防止字段名重复
    for (int i=0; i<[result columnCount]; i++) {
            NSString * columnName = [result columnNameForIndex:i];
            if ([columnName containsString:SYNC_ALBUM_MUSIC_COUNT]) {
                return YES;
            }
        }
    

    如果有朋友需要查询字段名字是否已经插入成功,可以参考FMDB提供的这些方法,只是代码,无需什么demo测试。继续保持技术的分享精神

    相关文章

      网友评论

          本文标题:FMDB 根据表名获取对应的列名是否存在

          本文链接:https://www.haomeiwen.com/subject/pydnkttx.html