sqlite 是完全限定视图中的字段名称
sqlite is fully qualifying field names in views
我找不到如何在通过视图查询时禁用 SQLite 中字段名称的完全限定。 (不要笑mtcars
,table命名是其他测试的症状...)
设置:
sqlite> create table mtcars (id int, mpg real, cyl int, vs int);
sqlite> insert into mtcars values (1, 21.0, 6, 0);
sqlite> insert into mtcars values (2, 22.8, 4, 1);
sqlite> insert into mtcars values (1, 21.4, 6, 1);
sqlite> .headers on
"Normal" table 访问,无浏览:
sqlite> select * from mtcars foo;
id|mpg|cyl|vs
1|21.0|6|0
2|22.8|4|1
1|21.4|6|1
sqlite> select foo.* from mtcars foo;
id|mpg|cyl|vs
1|21.0|6|0
2|22.8|4|1
1|21.4|6|1
sqlite> select foo.mpg,foo.cyl from mtcars foo;
mpg|cyl
21.0|6
22.8|4
21.4|6
目前一切正常。创建和使用视图:
sqlite> create view vwmtcars as select mpg,cyl from mtcars;
sqlite> select * from vwmtcars foo;
mpg|cyl
21.0|6
22.8|4
21.4|6
sqlite> select foo.* from vwmtcars foo;
mpg|cyl
21.0|6
22.8|4
21.4|6
还是正常的。然而:
sqlite> select foo.mpg,foo.cyl from vwmtcars foo;
foo.mpg|foo.cyl
21.0|6
22.8|4
21.4|6
我期待 mpg|cyl
,而不是 foo.mpg|foo.cyl
。
两个问题:
- 为什么字段名称是完全限定的?
- 我可以禁用它吗?
(Win10 x64, sqlite3 3.14.2 (包含在 Git-for-Windows 2.11.1))
解决方法是使用别名重置列名:
select f.mpg as mpg,f.cyl as cyl from vwmtcars f;
mpg|cyl
21.0|6
22.8|4
21.4|6
进一步说明,以供日后参考。
两个 SQLite's Pragmas 相关:short_column_names
(当前设置为 1
)和 full_column_names
(当前设置为 0
)。两者均已弃用。
根据用于命名返回列的逻辑(转述,上面 pragma link 中的全文):
- 如果有
AS
子句,则使用它。
- 如果是表达式,就使用它。
- 如果
short_column_names
为真,则仅使用列名。
- 如果
*_column_names
都为假,规则 2 适用。
- 使用
TABLE.COLUMN
此安装的事实:
pragma compile_options
没有列出OMIT_DEPRECATED
,所以这两个pragma是可用且有效的(尽管不鼓励);
short_column_names
为真,full_column_names
为假(我都没改);
据此,我推断 SQLite 将别名 VIEW 和列名视为 表达式 ,因此在案例 2 中得到解决并且从不检查对于情况 3 或以后的编译指示。
我倾向于的解决方案(正如@gregory 刚刚回答的那样)是明确命名每个变量(select foo.mpg as mpg, foo.cyl as cyl ...
)。尽管这看起来像是解决了症状而不是潜在的逻辑缺陷,但它与 SQL 代码中的(许多)最佳实践之一一致:始终是明确的。
我找不到如何在通过视图查询时禁用 SQLite 中字段名称的完全限定。 (不要笑mtcars
,table命名是其他测试的症状...)
设置:
sqlite> create table mtcars (id int, mpg real, cyl int, vs int);
sqlite> insert into mtcars values (1, 21.0, 6, 0);
sqlite> insert into mtcars values (2, 22.8, 4, 1);
sqlite> insert into mtcars values (1, 21.4, 6, 1);
sqlite> .headers on
"Normal" table 访问,无浏览:
sqlite> select * from mtcars foo;
id|mpg|cyl|vs
1|21.0|6|0
2|22.8|4|1
1|21.4|6|1
sqlite> select foo.* from mtcars foo;
id|mpg|cyl|vs
1|21.0|6|0
2|22.8|4|1
1|21.4|6|1
sqlite> select foo.mpg,foo.cyl from mtcars foo;
mpg|cyl
21.0|6
22.8|4
21.4|6
目前一切正常。创建和使用视图:
sqlite> create view vwmtcars as select mpg,cyl from mtcars;
sqlite> select * from vwmtcars foo;
mpg|cyl
21.0|6
22.8|4
21.4|6
sqlite> select foo.* from vwmtcars foo;
mpg|cyl
21.0|6
22.8|4
21.4|6
还是正常的。然而:
sqlite> select foo.mpg,foo.cyl from vwmtcars foo;
foo.mpg|foo.cyl
21.0|6
22.8|4
21.4|6
我期待 mpg|cyl
,而不是 foo.mpg|foo.cyl
。
两个问题:
- 为什么字段名称是完全限定的?
- 我可以禁用它吗?
(Win10 x64, sqlite3 3.14.2 (包含在 Git-for-Windows 2.11.1))
解决方法是使用别名重置列名:
select f.mpg as mpg,f.cyl as cyl from vwmtcars f;
mpg|cyl
21.0|6
22.8|4
21.4|6
进一步说明,以供日后参考。
两个 SQLite's Pragmas 相关:short_column_names
(当前设置为 1
)和 full_column_names
(当前设置为 0
)。两者均已弃用。
根据用于命名返回列的逻辑(转述,上面 pragma link 中的全文):
- 如果有
AS
子句,则使用它。 - 如果是表达式,就使用它。
- 如果
short_column_names
为真,则仅使用列名。 - 如果
*_column_names
都为假,规则 2 适用。 - 使用
TABLE.COLUMN
此安装的事实:
pragma compile_options
没有列出OMIT_DEPRECATED
,所以这两个pragma是可用且有效的(尽管不鼓励);short_column_names
为真,full_column_names
为假(我都没改);
据此,我推断 SQLite 将别名 VIEW 和列名视为 表达式 ,因此在案例 2 中得到解决并且从不检查对于情况 3 或以后的编译指示。
我倾向于的解决方案(正如@gregory 刚刚回答的那样)是明确命名每个变量(select foo.mpg as mpg, foo.cyl as cyl ...
)。尽管这看起来像是解决了症状而不是潜在的逻辑缺陷,但它与 SQL 代码中的(许多)最佳实践之一一致:始终是明确的。