【问题标题】:SQLite column names for SQL with subselect statements now prefix column name with table name带有子选择语句的 SQL 的 SQLite 列名现在以表名作为列名的前缀
【发布时间】:2017-11-06 17:36:08
【问题描述】:

在 iOS 11 中,如果您将 sqlite3_column_name 与带有子选择语句的 SQL 一起使用,它现在会返回带有表前缀的列名,而 iOS 10 则不会。

例如考虑这个 SQL:

SELECT f.foo_value, b.bar_value
  FROM foo as f LEFT JOIN
    (SELECT * FROM bar) AS b ON f.foo_id = b.foo_id

如果您随后使用 sqlite3_column_name 检索列名(注意这是 Objective-C sn-p,但这是 SQLite 问题,不是 Objective-C 或 Swift 独有的):

const char *name1 = sqlite3_column_name(statement, 0);
const char *name2 = sqlite3_column_name(statement, 1);

NSLog(@"SQLite version: %s", sqlite3_version);
NSLog(@"name of column 0: %s", name1);
NSLog(@"name of column 1: %s", name2);

在 iOS 11.1 中,这会报告:

SQLite 版本:3.19.3
第 0 列的名称:f.foo_value
第 1 列的名称:b.bar_value

在 iOS 10.1 中,此报告:

SQLite 版本:3.14.0
第 0 列的名称:foo_value
第 1 列的名称:bar_value

为什么?

顺便说一句,这个问题似乎只在 SQL 包含子选择语句时才会出现。

【问题讨论】:

    标签: ios sqlite ios11


    【解决方案1】:

    正如 SQLite documentation for sqlite3_column_name 所说:

    如果存在 AS 子句,则结果列的名称是该列的“AS”子句的值。如果没有 AS 子句,则列的名称是未指定的,并且可能会从 SQLite 的一个版本更改为下一个版本。

    因此,如果您想将sqlite3_column_name 的结果用于信息以外的任何目的,您确实应该在您的SQL 中使用AS 子句,例如

    SELECT f.foo_value AS foo_value, b.bar_value AS bar_value
      FROM ...
    

    作为Gwendal Roué noted,这是iOS 11附带的SQLite版本中引入的一个已知问题:

    此更改已在 SQLite 3.19.0 中引入。它存在于 iOS 11 附带的 SQLite 3.19.3 中。它已在 SQLite 3.20.0 中恢复。

    有关详细信息,请参阅:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多