带有子选择语句的SQL的SQLite列名称现在使用表名称作为列名称的前缀

时间:2017-11-06 17:36:08

标签: ios sqlite ios11

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

E.g。考虑这个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片段,但这是一个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包含子选择语句时才会显现出来。

1 个答案:

答案 0 :(得分: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中恢复。

     

有关详细信息,请参阅: