【问题标题】:Use column name instead of number with sqlite3_column_text在 sqlite3_column_text 中使用列名而不是数字
【发布时间】:2011-09-15 16:49:25
【问题描述】:

有什么方法可以使用列名而不是 int 作为列号:(char*)sqlite3_column_text(statement, 1)

这就是我现在所做的:

sqlite3 *db = [MyAppDelegate getNewDBConnection];
sqlite3_stmt *statement = nil;

const char *sql = "select * from foo f join bar b on b.id = f.id;";

if(sqlite3_prepare_v2(db, sql, -1, &statement, NULL) != SQLITE_OK)
   NSAssert1(0,@"Error preparing statement %s", sqlite3_errmsg(db));
       else
       {
           while(sqlite3_step(statement) == SQLITE_ROW) {

               [lorem addObject:[NSString stringWithFormat:@"%s",(char*)sqlite3_column_text(statement, 1)]];

               [ipsum addObject:[NSString stringWithFormat:@"%s",(char*)sqlite3_column_text(statement, 7)]];

           }   

           sqlite3_finalize(statement);

       }

但理想情况下我会这样做(char*)sqlite3_column_text(statement, SomeColumn)

【问题讨论】:

  • 如果您在select 语句中明确列出列(而不是执行select *),则不必担心顺序或列号会发生变化。

标签: iphone objective-c ios sqlite


【解决方案1】:

首先,看看 Objective-C 的 FMDB 包装器,它将为您节省大量原始 SQLite 编码。 (FMDB 信息:http://gusmueller.com/blog/archives/2008/06/new_home_for_fmdb.html

我不知道传递列名的方法。但是,如果您更改 SQL 并在那里命名列,而不是“选择 *”,它会简化事情,并且更健壮。

const char *sql = "select f.name, b.address, b.phone ... 

然后,访问器只需传递列号 1、2、3、4,... 比幻数 1 和 7 好得多!

name    = sqlite3_column_text(statement, 1)
address = sqlite3_column_text(statement, 2)
phone   = sqlite3_column_text(statement, 3)
...

【讨论】:

  • 哇,我觉得自己很愚蠢。我想我是非常专注于这个问题才能看到这个简单的解决方案:)
  • 总是希望您的代码提取正确的值绝对不是一件愚蠢的事情,尤其是当您稍后返回并更改该选择语句时:)。
【解决方案2】:

似乎没有直接的方法可以做到这一点。我所做的是 a) 通过 sqlite3_column_count() 获取结果中的字段数

b) 然后我创建了一个字典来映射值

c) 然后我将遍历列并使用键/值对填充字典 列名/索引

现在,您有一个映射字典,其中包含列名的索引。您可以使用它通过使用列名来获取列的索引。

这是我的代码 sn-p。希望对你有帮助!!!

        int columnCount = sqlite3_column_count(statement);

        NSMutableDictionary *mapper=[[NSMutableDictionary alloc] init];
        for(int i=0;i<columnCount;i++){
            const char *_columnName=sqlite3_column_name(statement, i);
            NSString *columnName=[[NSString alloc] initWithUTF8String:_columnName];
            [mapper setObject:[NSNumber numberWithInteger:i] forKey:columnName];
        }

【讨论】:

  • int columnCount = sqlite3_column_count(statement);
  • 很棒的家伙,获取列名。
【解决方案3】:

您甚至可以创建一个结构来将您的 sql 字段名称映射到列号,然后您可以像这样访问您的字段; name = sqlite3_column_text(statement, tablename_struct.name) - 实际上我现在正在做类似的事情。

    struct ElementsStructure {
        int ID; 
        int Slug; 
        int Title; 
        int Value; 
        int Type; 
        int Flags; 
        int Index;
        int Options; 
    };
    //field to column mappings for sql lite queries
    struct ElementsStructure oElements;
    oElements.ID = 0;
    oElements.Slug = 1; 
    oElements.Title = 2; 
    oElements.Value = 3; 
    oElements.Type = 4; 
    oElements.Flags = 5; 
    oElements.Index = 6;
    oElements.Options = 7; 

...

    NSNumber *ID = [NSNumber numberWithInt: sqlite3_column_int(statement, oElements.ID)];

我只是喜欢这种方法,因为如果将结构命名为实际的表名,它提供了一种超级简单的方法来直观地关联您分配的内容……尤其是对于可能正在查看您的代码的其他人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-25
    • 2015-07-19
    • 2011-12-06
    • 1970-01-01
    • 2018-01-22
    • 1970-01-01
    • 2018-03-08
    • 1970-01-01
    相关资源
    最近更新 更多