Является ли пробел необязательным в запросах SQL? - PullRequest
2 голосов
/ 09 февраля 2011

Я заметил, что при использовании 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 - токен, который служит псевдонимом).

Ответы [ 4 ]

3 голосов
/ 09 февраля 2011

Грамматика BNF SQL-92 здесь явно заявляет, что разделители (скобки, пробелы, * и т. Д.) Действительны для разбиения токенов, что делает необязательным white space в различных случаях, когда другие разделители уже ломаются до жетонов.

Это верно не только для SQLite и Oracle, но, по крайней мере, для MySQL и SQL Server (с которыми я работал и проверял), поскольку это указано в определении языка.

2 голосов
/ 09 февраля 2011

Пробел является необязательным практически во всех языках, где нет необходимости сохранять границы между ключевыми словами и / или идентификаторами.Вы могли бы написать код на C #, который выглядел бы как ваш SQL, и до тех пор, пока компилятор все еще может анализировать идентификаторы и ключевые слова, это не заботит.Единственное место, где пробел необходим для отделения ключевых слов от других буквенных символов.Повсюду, некоторые не алфавитно-цифровые символы (которые не являются частью какого-либо ключевого слова в SQL) разделяют ключевые слова, поэтому анализатор SQL все еще может переварить этот оператор.Пока это правда, пробел предназначен исключительно для удобства чтения.

1 голос
/ 09 февраля 2011

Я думаю, что это побочный эффект парсера.

Обычно компиляторы игнорируют пробелы через блоки SKIP , которые являются токенами, игнорируемыми компилятором, но вызывают ошибки, если они находятся в середине зарезервированного слова. Например, в C: «while» допустимо, «whi le» - нет, хотя пробел - это токен SKIP.

Причина в том, что он упрощает синтаксический анализатор, в противном случае им придется управлять всем пробелом, и это может быть довольно сложно, если вы не установите строгие правила, как это делает Python, но это будет трудно навязать поставщикам, таким как Oracle и сделает SQL более сложным, чем следовало бы.

И это упрощение имеет (непреднамеренный?) Побочный эффект от возможности удалить МОСТ (не все) пробелы. Имейте в виду, что в некоторых случаях удаление пробелов может привести к ошибкам компиляции (невозможно удалить пробел в GROUP BY, поскольку это является частью токена).

1 голос
/ 09 февраля 2011

Большая часть этого действительна просто потому, что вы заключили ключевые разделы в круглые скобки, где обычно требуется пробел.

...