我注意到使用Oracle或SQLite,这样的查询是完全有效的
SELECT*FROM(SELECT a,MAX(b)i FROM c GROUP BY a)WHERE(a=1)OR(i=2);
这是SQL的“功能”,查询的关键字或单词不需要用空格包围吗?如果是这样,为什么这样设计呢? SQL被设计为可读的,这似乎是一种混淆形式(特别是MAX(b)i
,其中i
是一个用作别名的标记。)
答案 0 :(得分:3)
SQL-92 BNF Grammar here明确指出分隔符(括号,空格,*等)对于分解标记是有效的,这使得white space
在其他分隔符已经分解标记的各种情况下是可选的。 / p>
这不仅适用于SQLite和Oracle,而且至少是MySQL和SQL Server(我使用并经过测试),因为它是在语言定义中指定的。
答案 1 :(得分:2)
在几乎任何语言中,空格是可选的,不一定要保留关键字和/或标识符之间的边界。您可以使用与SQL类似的C#编写代码,只要编译器仍然可以解析标识符和关键字,它就不关心了。
一个例子:您的语句的子查询是唯一需要空格以将关键字与其他字母字符分开的地方。在其他任何地方,一些非字母数字字符(不是SQL中任何关键字的一部分)将关键字分开,因此SQL解析器仍然可以消化此语句。只要这是真的,空白纯粹是为了人类的可读性。
答案 2 :(得分:1)
这大部分是有效的,因为你在括号中包含了通常需要空格的关键部分。
答案 3 :(得分:1)
我认为这是解析器的副作用。
通常编译器会通过块 SKIP 忽略空格,这些块是编译器忽略的标记,但如果在保留字的中间则会导致错误。例如在C:'while'有效,'whi le'不是,虽然空格是SKIP令牌。
原因是它简化了解析器,如果没有,他们将不得不管理所有的空白区域,除非像Python那样设置严格的规则,否则这可能非常复杂,但这对Oracle这样的供应商来说很难实施并且会使SQL变得更加复杂。
这种简化有(无意的?)副作用,能够移除MOST(不是全部)空白区域。请注意,在某些情况下,删除空格可能会导致编译错误(无法删除GROUP BY中的空格,因为它是令牌的一部分)。