`您的SQL语法有错误;`在查询中使用*时



我有查询,它可以

select *, id, from_unixtime(start_timestamp) from log limit 1;

这也很好:

select * from log limit 1;

如果将*移动到末尾,为什么会出现错误?

select id, from_unixtime(start_timestamp), * from log limit 1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '* from log limit 1' at line 1

原因是他们在SQL解析器中实现了一条捷径。

SQL-2003规范显示SELECT的语法规则如下:

<query specification> ::=
SELECT [ <set quantifier> ] <select list> <table expression>
<select list> ::=
<asterisk>
| <select sublist> [ { <comma> <select sublist> }... ]
<select sublist> ::=
<derived column>
| <qualified asterisk>

这表明SELECT *与逗号分隔列或限定星号的列表互斥。如果使用不合格的*,那么这必须是整个选择列表。为了实现这种语法,它们需要<select list>规则和<select sublist>规则。

但是MySQL的SQL解析器Yacc文件显示:

query_specification:
SELECT_SYM
select_options
select_item_list
...
select_item_list:
select_item_list ',' select_item
| select_item
| '*'

他们基本上将<select list><select sublist>的规则合并为一个递归规则。因此,他们对select_item_list的规则允许SELECT *, <select_item>, <select_item>, ...,而根据SQL-2003标准,它不应该允许。

由于他们语法中的这个捷径,他们不允许*通配符作为select_item_list中的尾随项。

如果MySQL要";"修复";现在这个问题,要使它符合标准语法规则,无疑将打破成千上万依赖非标准语法的遗留应用程序。

您可以通过避免SELECT *, ...语法来使代码符合标准语法。仅使用SELECT * FROM ...。您也可以合法地使用限定星号,如SELECT t1.*, ...

相关内容

最新更新