2011-02-09 51 views
2

我注意到,使用Oracle或SQLite的,類似這樣的查詢是完全有效的在SQL查詢中可用空白嗎?

SELECT*FROM(SELECT a,MAX(b)i FROM c GROUP BY a)WHERE(a=1)OR(i=2); 

是那個查詢的關鍵字或詞不必用空格來包圍SQL的「功能」?如果是這樣,爲什麼這樣設計? SQL被設計爲可讀,這似乎是一種混淆形式(特別是MAX(b)i,其中i是一個用作別名的標記)。

回答

2

SQL-92 BNF Grammar here明確指出分隔符(括號,空格,*等)有效分解令牌,這使white space在其他分隔符已經分解令牌的情況下可選。

這不僅適用於SQLite和Oracle,而且MySQL和SQL Server至少(我使用並經過測試),因爲它是在語言定義中指定的。

2

在絕大多數情況下,在保留關鍵字和/或標識符之間的邊界時,空白是可選的。你可以用C#編寫類似於你的SQL的代碼,只要編譯器仍然可以解析標識符和關鍵字,它並不關心。

案例:您的語句的子查詢是唯一需要用空格分隔其他字母字符的關鍵字的地方。在其他地方,某些非字母數字字符(它們不是SQL中任何關鍵字的一部分)會分隔關鍵字,因此SQL解析器仍可以摘錄此語句。只要這是真的,空白純粹是爲了人類的可讀性。

1

大部分情況僅僅因爲您已將關鍵部分包含在通常需要使用空格的括號中。

1

我認爲這是解析器的副作用。

通常情況下,編譯器將忽略通過塊SKIP的空白,它們是編譯器忽略的令牌,但如果在保留字的中間會導致錯誤。例如在C中:'while'有效,'whi le'不是,儘管空格是SKIP標記。

原因是它簡化了解析器,如果不是,他們將不得不管理所有的空白,並且這可能會非常複雜,除非您設置像Python那樣嚴格的規則,但是這對於像這樣的供應商來說很難實現甲骨文,並會使SQL比它應該更復雜。

並且該簡化具有能夠移除MOST(不是全部)空白的(無意的)副作用。請注意,在某些情況下,刪除空白可能會導致編譯錯誤(無法刪除GROUP BY中的空間,因爲它是標記的一部分)。