SQLSQL 的带有子选择语句的 SQLite 列名称现在用 table 名称作为列名称的前缀
SQLite column names for SQL with subselect statements now prefix column name with table name
在 iOS 11 中,如果您将 sqlite3_column_name
和 SQL 与子选择语句一起使用,它现在 returns 带有 table 前缀的列名,而 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 片段,但这是 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 version: 3.19.3
name of column 0: f.foo_value
name of column 1: b.bar_value
在 iOS 10.1 中,此报告:
SQLite version: 3.14.0
name of column 0: foo_value
name of column 1: bar_value
为什么?
顺便说一句,这个问题似乎只在 SQL 包含子选择语句时才会出现。
正如 SQLite documentation for sqlite3_column_name
所说:
The name of a result column is the value of the "AS" clause for that column, if there is an AS clause. If there is no AS clause then the name of the column is unspecified and may change from one release of SQLite to the next.
因此,如果您想将 sqlite3_column_name
的结果用于提供信息以外的任何用途,您确实应该在 SQL 中使用 AS
子句,例如
SELECT f.foo_value AS foo_value, b.bar_value AS bar_value
FROM ...
As Gwendal Roué noted,这是 iOS11 附带的 SQLite 版本中引入的已知问题:
This change has been introduced in SQLite 3.19.0. It is present in SQLite 3.19.3 shipped with iOS 11. It has been reverted in SQLite 3.20.0.
For more information, see:
- Ticket: https://sqlite.org/src/info/de3403bf5ae5f72ed
- Mailing-list: http://mailinglists.sqlite.org/cgi-bin/mailman/private/sqlite-users/2017-July/073955.html
- SQLite 3.20.0 release notes: https://sqlite.org/changes.html#version_3_20_0
在 iOS 11 中,如果您将 sqlite3_column_name
和 SQL 与子选择语句一起使用,它现在 returns 带有 table 前缀的列名,而 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 片段,但这是 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 version: 3.19.3
name of column 0: f.foo_value
name of column 1: b.bar_value
在 iOS 10.1 中,此报告:
SQLite version: 3.14.0
name of column 0: foo_value
name of column 1: bar_value
为什么?
顺便说一句,这个问题似乎只在 SQL 包含子选择语句时才会出现。
正如 SQLite documentation for sqlite3_column_name
所说:
The name of a result column is the value of the "AS" clause for that column, if there is an AS clause. If there is no AS clause then the name of the column is unspecified and may change from one release of SQLite to the next.
因此,如果您想将 sqlite3_column_name
的结果用于提供信息以外的任何用途,您确实应该在 SQL 中使用 AS
子句,例如
SELECT f.foo_value AS foo_value, b.bar_value AS bar_value
FROM ...
As Gwendal Roué noted,这是 iOS11 附带的 SQLite 版本中引入的已知问题:
This change has been introduced in SQLite 3.19.0. It is present in SQLite 3.19.3 shipped with iOS 11. It has been reverted in SQLite 3.20.0.
For more information, see:
- Ticket: https://sqlite.org/src/info/de3403bf5ae5f72ed
- Mailing-list: http://mailinglists.sqlite.org/cgi-bin/mailman/private/sqlite-users/2017-July/073955.html
- SQLite 3.20.0 release notes: https://sqlite.org/changes.html#version_3_20_0