There are at least a couple of issues:
- There are lots of versions of the standard: 1986, 1989, 1992, (some work circa 1996), 1999, 2003, 2008, and 2011 editions.
- The standard has multiple parts these days. There is the SQL/Foundation (core SQL), but also lots of optional extensions.
- Each DBMS has its own extensions to the SQL standard, and they all omit some aspects of the standard too.
You can find the BNF (Backus-Naur Format) grammars for some versions of the standard available here. These are heavily hyperlinked HTML. However, the standard is not just the SQL grammar; there are lots (and lots, and lots) of rules about what is allowed where and when (and not usually much explanation of why) in the rest of the standard. The standard is almost impossibly opaque at times.
Here's a tame example from ISO/IEC 9075-2:2003 (E) — that's SQL/Foundation for SQL-2003:
10.7 <collate clause>
Function
Specify a default collation.
Format
<collate clause> ::= COLLATE <collation name>
Syntax Rules
1) Let C be the <collation name>
contained in the <collate clause>
. The schema identified by the explicit or
implicit qualifier of the <collation name>
shall include the descriptor of C.
Access Rules
1) Case:
a) If <collate clause>
is contained, without an intervening <SQL routine spec>
that specifies SQL SECURITY INVOKER, in an <SQL schema statement>
, then the applicable privileges of the
<authorization identifier>
that owns the containing schema shall include USAGE on C.
b) Otherwise, the current privileges shall include USAGE on C.
NOTE 228 — “applicable privileges” and “current privileges” are defined in Subclause 12.3, “<privileges>
”.
General Rules
None.
Conformance Rules
1) Without Feature F690, “Collation support”, conforming SQL language shall not contain a <collate clause>
.
A less tame example is that <cast specification>
has 16 pages of gobbledygook describing it. This is from about 2/3 of the way through. It is 'General Rule' number 16 (out of 20):
16) If TD is the datetime data type TIME WITH TIME ZONE, then let TSP be the <time precision>
of TD.
Case:
a) If SD is character string, then SV is replaced by:
TRIM ( BOTH ' ' FROM VE )
Case:
i) If the rules for <literal>
or for <unquoted time string>
in Subclause 5.3, “<literal>
”, can be
applied to SV to determine a valid value of the data type TD, then let TV be that value.
ii) If the rules for <literal>
or for <unquoted time string>
in Subclause 5.3, “<literal>
”, can be
applied to SV to determine a valid value of the data type TIME(TSP) WITHOUT TIME ZONE,
then let TV1 be that value and let TV be the value of:
CAST ( TV1 AS TIME(TSP) WITH TIME ZONE )
iii) If a <datetime value>
does not conform to the natural rules for dates or times according to the
Gregorian calendar, then an exception condition is raised: data exception — invalid datetime
format.
iv) Otherwise, an exception condition is raised: data exception — invalid character value for cast.
b) If SD is TIME WITH TIME ZONE, then TV is SV, with implementation-defined rounding or truncation
if necessary.
c) If SD is TIME WITHOUT TIME ZONE, then the UTC component of TV is SV – STZD, computed
modulo 24 hours, with implementation-defined rounding or truncation if necessary, and the time zone
component of TV is STZD.
d) If SD is TIMESTAMP WITH TIME ZONE, then the UTC component of TV is the hour, minute, and
second <primary datetime field>
s of SV, with implementation-defined rounding or truncation if necessary,
and the time zone component of TV is the time zone displacement of SV.
e) If SD is TIMESTAMP WITHOUT TIME ZONE, then TV is:
CAST ( CAST ( SV AS TIMESTAMP(TSP) WITH TIME ZONE )
AS TIME(TSP) WITH TIME ZONE )
The indentation is a little better in the standard, and you'd have a little more context for some of the names (such as TV, SV, SD, etc.), but the language used is really that turgid.