SQL 样式指南

1,158 阅读13分钟
原文链接: www.sqlstyle.guide

这篇文档翻译自以署名-相同方式共享 4.0 国际协议发布的www.sqlstyle.guide,译文以原文同样的协议发布。

Overview 综述

你可以直接使用这些指导方针,或者fork后创建自己的版本——最重要的是选择一套方针并严格遵守它。欢迎通过提交issuepull request来提交建议或修复bug。

为了让阅读了Joe Celko的《SQL ProgrammingStyle》的团队能更容易采用这套规则, 这套原则被设计成与该书的兼容的形式。该指南在某些领域严格一些,在另一些领域松懈一些。 当然该指南比Celko的书更简洁一些,因为Celko的书包含了一些趣闻和每一条原则后的理由。

将该文档的Markdown format格式添加到项目代码库中或将该页面的链接发送给所有项目的参与者要比传阅实体书容易得多。

Simon Holywell所著的《SQL样式指南》以署名-相同方式共享 4.0 国际协议发布,改编自 www.sqlstyle.guide

General 一般原则

Do 应该做的事情

  • 使用一致的、叙述性的名称。
  • 灵活使用空格和缩进来增强可读性。
  • 存储符合ISO-8601标准的日期格式(YYYY-MM-DD HH:MM:SS.SSSSS)。
  • 最好使用标准SQL函数而不是特定供应商的函数以提高可移植性。
  • 保证代码简洁明了并消除多余的SQL——比如非必要的引号或括号,或者可以推导出的多余WHERE语句。
  • 必要时在SQL代码中加入注释。优先使用C语言式的以/*开始以*/结束的块注释,或使用以--开始的行注释。
SELECT file_hash  -- stored ssdeep hash
  FROM file_system
 WHERE file_name = '.vimrc';
/* Updating the file record after writing to the file */
UPDATE file_system
   SET file_modified_date = '1980-02-22 13:19:01.00000',
       file_size = 209732
 WHERE file_name = '.vimrc';

Avoid 应避免的事情

  • 驼峰命名法——它不适合快速扫描。
  • 描述性的前缀或匈牙利命名法比如sp_tbl
  • 复数形式——尽量使用更自然的集合术语。比如,用“staff”替代“employees”,或用“people”替代“individuals”。
  • 需要引用号的标识符——如果你必须使用这样的标识符,最好坚持用SQL92的双引号来提高可移植性。
  • 面向对象编程的原则不该应用到结构化查询语言或数据库结构上。

Naming conventions 命名惯例

General 一般原则

  • 保证名字独一无二且不是保留字
  • 保证名字长度不超过30个字节。
  • 名字要以字母开头,不能以下划线结尾。
  • 只在名字中使用字母、数字和下划线。
  • 不要在名字中出现连续下划线——这样很难辨认。
  • 在名字中需要空格的地方用下划线代替。
  • 尽量避免使用缩写词。使用时一定确定这个缩写简明易懂。
SELECT first_name
  FROM staff;

Tables 表名

  • 用集群名称,或在不那么理想的情况下,复数形式。如staffemployees
  • 不要使用类似tbl或其他的描述性的前缀或匈牙利命名法。
  • 表不应该同它的列同名,反之亦然。
  • 尽量避免连接两个表的名字作为关系表(relationship table)的名字。与其使用cars_mechanics做表名不如使用services

Columns 列名

  • 总是使用单数形式。
  • 避免直接使用id做表的主标识符。
  • 避免列名同表名同名,反之亦然。
  • 总是使用小写字母,除非是特殊情况,如专有名词。

Aliasing or correlations 别名与关联名

  • 应该与它们别名的对象或与它们代表的表达式相关联。
  • 一般来说,关联名应该是对象名的第一个字母。
  • 如果已经有相同的关联名了,那么在关联名后加一个数字。
  • 总是加上AS关键字,因为这样的显示声明易于阅读。
  • 为计算出的数据命名时,用一个将这条数据存在表里时会使用的列名。
SELECT first_name AS fn
  FROM staff AS s1
  JOIN students AS s2
    ON s2.mentor_id = s1.staff_num;
SELECT SUM(s.monitor_tally) AS monitor_total
  FROM staff AS s;

Stored procedures 过程名

  • 名字一定要包含动词。
  • 不要附加sp_或任何其他这样的叙述性前缀或使用匈牙利表示法。

Uniform suffix 统一的后缀

下列后缀有统一的意义,能保证SQL代码更容易被理解。在合适的时候使用正确的后缀。

  • _id 独一无二的标识符,如主键。
  • _status 标识值或任何表示状态的值,比如publication_status
  • _total 总和或某些值的和。
  • _num 表示该域包含数值。
  • _name 表示名字。
  • _seq 包含一系列数值。
  • _date 表示该列包含日期。
  • _tally 计数值。
  • _size 大小,如文件大小或服装大小。
  • _addr 地址,有形的或无形的,如ip_addr

Query syntax 查询语句

Reserved words 保留字

保留字总是大写,如SELECTWHERE

最好使用保留字的全称而不是简写,用ABSOLUTE而不用ABS

当标准ANSI SQL关键字能完成相同的事情时,不要使用数据库服务器相关的关键字,这样能增强可移植性。

SELECT model_num
  FROM phones AS p
 WHERE p.release_date > '2014-09-30';

White space 空白字符

正确地使用空白字符对清晰的代码十分重要。不要把代码堆再一起或移除自然语言中的空格。

Spaces 空格

用空格使根关键字都结束在同一列上。在代码中形成一个从上到下的“川流”,这样帮助读者快速扫描代码并将关键字和实现细节分开。川流在排版时应该避免,但是对书写SQL语句是有帮助的。

(SELECT f.species_name,
        AVG(f.height) AS average_height, AVG(f.diameter) AS average_diameter
   FROM flora AS f
  WHERE f.species_name = 'Banksia'
     OR f.species_name = 'Sheoak'
     OR f.species_name = 'Wattle'
  GROUP BY f.species_name, f.observation_date)

  UNION ALL

(SELECT b.species_name,
        AVG(b.height) AS average_height, AVG(b.diameter) AS average_diameter
   FROM botanic_garden_flora AS b
  WHERE b.species_name = 'Banksia'
     OR b.species_name = 'Sheoak'
     OR b.species_name = 'Wattle'
  GROUP BY b.species_name, b.observation_date)

注意WHEREFROM等关键字,都右对齐,而真实的列名都左对齐。

注意下列情况总是加入空格:

  • 在等号前后(=
  • 在逗号后(,
  • 单引号前后('),除非单引号后面是括号、逗号或分号
SELECT a.title, a.release_date, a.recording_date
  FROM albums AS a
 WHERE a.title = 'Charcoal Lane'
    OR a.title = 'The New Danger';

Line spacing 换行

总是换行的情况:

  • ANDOR前。
  • 在分号后(分隔语句以提高可读性)。
  • 在每个关键词定以后。
  • 将多个列组成一个逻辑组时的逗号后。
  • 将代码分隔成相关联的多个部分,帮助提高大段代码的可读性。

让所有的关键字右对齐,让所有的值左对齐,在查询语句中间留出一个空隙。这样能提高速读代码的速读。

INSERT INTO albums (title, release_date, recording_date)
VALUES ('Charcoal Lane', '1990-01-01 01:01:01.00000', '1990-01-01 01:01:01.00000'),
       ('The New Danger', '2008-01-01 01:01:01.00000', '1990-01-01 01:01:01.00000');
UPDATE albums
   SET release_date = '1990-01-01 01:01:01.00000'
 WHERE title = 'The New Danger';
SELECT a.title,
       a.release_date, a.recording_date, a.production_date -- grouped dates together
  FROM albums AS a
 WHERE a.title = 'Charcoal Lane'
    OR a.title = 'The New Danger';

Identation 缩进

为确保SQL的可读性,一定要遵守下列规则。

Joins Join语句

Join语句应该缩进到川流的另一侧并在必要的时候添加一个换行。

SELECT r.last_name
  FROM riders AS r
       INNER JOIN bikes AS b
       ON r.bike_vin_num = b.vin_num
          AND b.engine_tally > 2

       INNER JOIN crew AS c
       ON r.crew_chief_last_name = c.last_name
          AND c.chief = 'Y';

Subqueries 子查询

子查询应该在川流的右侧对齐并使用其他查询相同的样式。有时候将右括号单独置于一行并同与它配对的左括号对齐是有意义的——尤其是当存在嵌套子查询的时候。

SELECT r.last_name,
       (SELECT MAX(YEAR(championship_date))
          FROM champions AS c
         WHERE c.last_name = r.last_name
           AND c.confirmed = 'Y') AS last_championship_year
  FROM riders AS r
 WHERE r.last_name IN
       (SELECT c.last_name
          FROM champions AS c
         WHERE YEAR(championship_date) > '2008'
           AND c.confirmed = 'Y');

Preferred formalisms 推荐的形式

  • 尽量使用BETWEEN而不是多个AND语句。
  • 同样地,使用IN()而不是多个OR语句。
  • 当数据输出数据库时需要处理时,使用CASE表达式。CASE语句能嵌套形成更复杂的逻辑结构。
  • 尽量避免UNION语句和临时表。如果数据库架构能够不靠这些语句运行,那么多数情况下它就不应该依靠这些语句。
SELECT CASE postcode
       WHEN 'BN1' THEN 'Brighton'
       WHEN 'EH1' THEN 'Edinburgh'
       END AS city
  FROM office_locations
 WHERE country = 'United Kingdom'
   AND opening_time BETWEEN 8 AND 9
   AND postcode IN ('EH1', 'BN1', 'NN1', 'KW1')

Create syntax 创建语句

声明模式信息时维护可读代码也很重要。所以列定义的顺序和分组一定要有意义。

CREATE定义中,每列要缩进4个空格。

Choosing data types 选择数据类型

  • 尽量不使用供应商相关的数据类型——这些类型可不能能在老系统上使用。
  • 只在真的需要浮点数运算的时候才使用REALFLOAT类型,否则使用NUMERICDECIMAL类型。浮点数舍入误差是个麻烦。

Specifying default values 指定默认类型

  • 默认值一定与列的类型相同——如果一个列的类型是DECIMAL那么就不要使用INTEGER类型作为默认值。
  • 默认值要紧跟类型声明并在NOT NULL声明前。

Constraints and keys 约束和键

约束和键是构成数据库系统的重要组成部分。它们能很快地变得难以阅读和理解,所以遵从指导方针是很重要的。

Choosing keys 选择键

设计时应该谨慎选择构成键的列,因为键既明显影响着性能和数据完整性。

  1. 键在某种程度上应该是独一无二的。
  2. 该值在不同表中的类型应该相同并且尽量不会更改。
  3. 该值是否会无法通过某种标准格式(如ISO发布的标准)?如
  4. 尽量让键保持简单,但在适当情况下不要害怕使用复合键。

以上是定义数据库时合乎逻辑的平衡做法。当需求变更时,键也应该根据情况更新。

Defining constraints 定义约束

确定键后,就可以用约束和字值段验证来定义它们。

General 概述
  • 表至少需要一个键来保证其完整性和可用性。
  • 约束应该有名字,除了UNIQUEPRIMARY KEYFOREIGN KEY之外。
Layout and order 布局和顺序
  • CREATE TABLE语句后先定义主键。
  • 约束的定义应该紧跟它相应的列的定义后。
  • 如果该约束与多个列相关,那么让它尽量离与其相关的列距离越近越好。实在不行就讲它放在表定义的最后。
  • 如果是与整个表相关联表级别的约束,那么就将放在表的定义的最后。
  • 按照字母顺序安排定义,ON DELETE排在ON UPDATE前。
  • 有道理的话,把所有相关的语句对齐。比如,把所有NOT NULL定义对齐到同一列。虽然这样的做法有些慢,但是能提高可读性。
Validation 校验
  • LIKESIMILAR TO约束来保证格式已知字符串的数据完整性。
  • 当数字的值的范围可以确定时,用CHECK()来防止错误的值进入数据库或被错误地转换。大部分情况下至少要确认值要大于零。
  • CHECK()约束应该在单独的语句中以便debug。
Example
CREATE TABLE staff (
    PRIMARY KEY (staff_num),
    staff_num      INT(5)       NOT NULL,
    first_name     VARCHAR(100) NOT NULL,
    pens_in_drawer INT(2)       NOT NULL,
                   CONSTRAINT pens_in_drawer_range
                   CHECK(pens_in_drawer >= 1 AND pens_in_drawer < 100)
);

Design to avoid

  • 面向对象设计思想并不适用于关系型数据库——避免这个陷阱。
  • 将值存入一列并将单位存在另一列。列的定义应该让自己的单位不言自明以避免在应用内进行合并。使用CHECK()来保证数据库中的数据是合法的。
  • EAV (Entity Attribute Value)表——用特殊的产品来处理无模式数据。
  • 因为某些原因(如为了归档、为了划分跨国公司的区域)将能合并在一起的表分开。这样的设计导致以后必须使用UNION操作而不能直接查询一个表。

附录

保留字参考

下表包含了ANSI SQL (92, 99 和 2003)、MySQL 3到5.x、PostgreSQL 8.1、MS SQL Server 2000、MS ODBC和Oracle 10.2中的关键字。

A
ABORT
ABS
ABSOLUTE
ACCESS
ACTION
ADA
ADD
ADMIN
AFTER
AGGREGATE
ALIAS
ALL
ALLOCATE
ALSO
ALTER
ALWAYS
ANALYSE
ANALYZE
AND
ANY
ARE
ARRAY
AS
ASC
ASENSITIVE
ASSERTION
ASSIGNMENT
ASYMMETRIC
AT
ATOMIC
ATTRIBUTE
ATTRIBUTES
AUDIT
AUTHORIZATION
AUTO_INCREMENT
AVG
AVG_ROW_LENGTH
BACKUP
BACKWARD
BEFORE
BEGIN
BERNOULLI
BETWEEN
BIGINT
BINARY
BIT
BIT_LENGTH
BITVAR
BLOB
BOOL
BOOLEAN
BOTH
BREADTH
BREAK
BROWSE
BULK
BY
C
CACHE
CALL
CALLED
CARDINALITY
CASCADE
CASCADED
CASE
CAST
CATALOG
CATALOG_NAME
CEIL
CEILING
CHAIN
CHANGE
CHAR
CHAR_LENGTH
CHARACTER
CHARACTER_LENGTH
CHARACTER_SET_CATALOG
CHARACTER_SET_NAME
CHARACTER_SET_SCHEMA
CHARACTERISTICS
CHARACTERS
CHECK
CHECKED
CHECKPOINT
CHECKSUM
CLASS
CLASS_ORIGIN
CLOB
CLOSE
CLUSTER
CLUSTERED
COALESCE
COBOL
COLLATE
COLLATION
COLLATION_CATALOG
COLLATION_NAME
COLLATION_SCHEMA
COLLECT
COLUMN
COLUMN_NAME
COLUMNS
COMMAND_FUNCTION
COMMAND_FUNCTION_CODE
COMMENT
COMMIT
COMMITTED
COMPLETION
COMPRESS
COMPUTE
CONDITION
CONDITION_NUMBER
CONNECT
CONNECTION
CONNECTION_NAME
CONSTRAINT
CONSTRAINT_CATALOG
CONSTRAINT_NAME
CONSTRAINT_SCHEMA
CONSTRAINTS
CONSTRUCTOR
CONTAINS
CONTAINSTABLE
CONTINUE
CONVERSION
CONVERT
COPY
CORR
CORRESPONDING
COUNT
COVAR_POP
COVAR_SAMP
CREATE
CREATEDB
CREATEROLE
CREATEUSER
CROSS
CSV
CUBE
CUME_DIST
CURRENT
CURRENT_DATE
CURRENT_DEFAULT_TRANSFORM_GROUP
CURRENT_PATH
CURRENT_ROLE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_TRANSFORM_GROUP_FOR_TYPE
CURRENT_USER
CURSOR
CURSOR_NAME
CYCLE
DATA
DATABASE
DATABASES
DATE
DATETIME
DATETIME_INTERVAL_CODE
DATETIME_INTERVAL_PRECISION
DAY
DAY_HOUR
DAY_MICROSECOND
DAY_MINUTE
DAY_SECOND
DAYOFMONTH
DAYOFWEEK
DAYOFYEAR
DBCC
DEALLOCATE
DEC
DECIMAL
DECLARE
DEFAULT
DEFAULTS
DEFERRABLE
DEFERRED
DEFINED
DEFINER
DEGREE
DELAY_KEY_WRITE
DELAYED
DELETE
DELIMITER
DELIMITERS
DENSE_RANK
DENY
DEPTH
DEREF
DERIVED
DESC
DESCRIBE
DESCRIPTOR
DESTROY
DESTRUCTOR
DETERMINISTIC
DIAGNOSTICS
DICTIONARY
DISABLE
DISCONNECT
DISK
DISPATCH
DISTINCT
DISTINCTROW
DISTRIBUTED
DIV
DO
DOMAIN
DOUBLE
DROP
DUAL
DUMMY
DUMP
DYNAMIC
DYNAMIC_FUNCTION
DYNAMIC_FUNCTION_CODE
EACH
ELEMENT
ELSE
ELSEIF
ENABLE
ENCLOSED
ENCODING
ENCRYPTED
END
END-EXEC
ENUM
EQUALS
ERRLVL
ESCAPE
ESCAPED
EVERY
EXCEPT
EXCEPTION
EXCLUDE
EXCLUDING
EXCLUSIVE
EXEC
EXECUTE
EXISTING
EXISTS
EXIT
EXP
EXPLAIN
EXTERNAL
EXTRACT
FALSE
FETCH
FIELDS
FILE
FILLFACTOR
FILTER
FINAL
FIRST
FLOAT
FLOAT4
FLOAT8
FLOOR
FLUSH
FOLLOWING
FOR
FORCE
FOREIGN
FORTRAN
FORWARD
FOUND
FREE
FREETEXT
FREETEXTTABLE
FREEZE
FROM
FULL
FULLTEXT
FUNCTION
FUSION
G
GENERAL
GENERATED
GET
GLOBAL
GO
GOTO
GRANT
GRANTED
GRANTS
GREATEST
GROUP
GROUPING
HANDLER
HAVING
HEADER
HEAP
HIERARCHY
HIGH_PRIORITY
HOLD
HOLDLOCK
HOST
HOSTS
HOUR
HOUR_MICROSECOND
HOUR_MINUTE
HOUR_SECOND
IDENTIFIED
IDENTITY
IDENTITY_INSERT
IDENTITYCOL
IF
IGNORE
ILIKE
IMMEDIATE
IMMUTABLE
IMPLEMENTATION
IMPLICIT
IN
INCLUDE
INCLUDING
INCREMENT
INDEX
INDICATOR
INFILE
INFIX
INHERIT
INHERITS
INITIAL
INITIALIZE
INITIALLY
INNER
INOUT
INPUT
INSENSITIVE
INSERT
INSERT_ID
INSTANCE
INSTANTIABLE
INSTEAD
INT
INT1
INT2
INT3
INT4
INT8
INTEGER
INTERSECT
INTERSECTION
INTERVAL
INTO
INVOKER
IS
ISAM
ISNULL
ISOLATION
ITERATE
JOIN
K
KEY
KEY_MEMBER
KEY_TYPE
KEYS
KILL
LANCOMPILER
LANGUAGE
LARGE
LAST
LAST_INSERT_ID
LATERAL
LEADING
LEAST
LEAVE
LEFT
LENGTH
LESS
LEVEL
LIKE
LIMIT
LINENO
LINES
LISTEN
LN
LOAD
LOCAL
LOCALTIME
LOCALTIMESTAMP
LOCATION
LOCATOR
LOCK
LOGIN
LOGS
LONG
LONGBLOB
LONGTEXT
LOOP
LOW_PRIORITY
LOWER
M
MAP
MATCH
MATCHED
MAX
MAX_ROWS
MAXEXTENTS
MAXVALUE
MEDIUMBLOB
MEDIUMINT
MEDIUMTEXT
MEMBER
MERGE
MESSAGE_LENGTH
MESSAGE_OCTET_LENGTH
MESSAGE_TEXT
METHOD
MIDDLEINT
MIN
MIN_ROWS
MINUS
MINUTE
MINUTE_MICROSECOND
MINUTE_SECOND
MINVALUE
MLSLABEL
MOD
MODE
MODIFIES
MODIFY
MODULE
MONTH
MONTHNAME
MORE
MOVE
MULTISET
MUMPS
MYISAM
NAME
NAMES
NATIONAL
NATURAL
NCHAR
NCLOB
NESTING
NEW
NEXT
NO
NO_WRITE_TO_BINLOG
NOAUDIT
NOCHECK
NOCOMPRESS
NOCREATEDB
NOCREATEROLE
NOCREATEUSER
NOINHERIT
NOLOGIN
NONCLUSTERED
NONE
NORMALIZE
NORMALIZED
NOSUPERUSER
NOT
NOTHING
NOTIFY
NOTNULL
NOWAIT
NULL
NULLABLE
NULLIF
NULLS
NUMBER
NUMERIC
OBJECT
OCTET_LENGTH
OCTETS
OF
OFF
OFFLINE
OFFSET
OFFSETS
OIDS
OLD
ON
ONLINE
ONLY
OPEN
OPENDATASOURCE
OPENQUERY
OPENROWSET
OPENXML
OPERATION
OPERATOR
OPTIMIZE
OPTION
OPTIONALLY
OPTIONS
OR
ORDER
ORDERING
ORDINALITY
OTHERS
OUT
OUTER
OUTFILE
OUTPUT
OVER
OVERLAPS
OVERLAY
OVERRIDING
OWNER
PACK_KEYS
PAD
PARAMETER
PARAMETER_MODE
PARAMETER_NAME
PARAMETER_ORDINAL_POSITION
PARAMETER_SPECIFIC_CATALOG
PARAMETER_SPECIFIC_NAME
PARAMETER_SPECIFIC_SCHEMA
PARAMETERS
PARTIAL
PARTITION
PASCAL
PASSWORD
PATH
PCTFREE
PERCENT
PERCENT_RANK
PERCENTILE_CONT
PERCENTILE_DISC
PLACING
PLAN
PLI
POSITION
POSTFIX
POWER
PRECEDING
PRECISION
PREFIX
PREORDER
PREPARE
PREPARED
PRESERVE
PRIMARY
PRINT
PRIOR
PRIVILEGES
PROC
PROCEDURAL
PROCEDURE
PROCESS
PROCESSLIST
PUBLIC
PURGE
QUOTE
RAID0
RAISERROR
RANGE
RANK
RAW
READ
READS
READTEXT
REAL
RECHECK
RECONFIGURE
RECURSIVE
REF
REFERENCES
REFERENCING
REGEXP
REGR_AVGX
REGR_AVGY
REGR_COUNT
REGR_INTERCEPT
REGR_R2
REGR_SLOPE
REGR_SXX
REGR_SXY
REGR_SYY
REINDEX
RELATIVE
RELEASE
RELOAD
RENAME
REPEAT
REPEATABLE
REPLACE
REPLICATION
REQUIRE
RESET
RESIGNAL
RESOURCE
RESTART
RESTORE
RESTRICT
RESULT
RETURN
RETURNED_CARDINALITY
RETURNED_LENGTH
RETURNED_OCTET_LENGTH
RETURNED_SQLSTATE
RETURNS
REVOKE
RIGHT
RLIKE
ROLE
ROLLBACK
ROLLUP
ROUTINE
ROUTINE_CATALOG
ROUTINE_NAME
ROUTINE_SCHEMA
ROW
ROW_COUNT
ROW_NUMBER
ROWCOUNT
ROWGUIDCOL
ROWID
ROWNUM
ROWS
RULE
SAVE
SAVEPOINT
SCALE
SCHEMA
SCHEMA_NAME
SCHEMAS
SCOPE
SCOPE_CATALOG
SCOPE_NAME
SCOPE_SCHEMA
SCROLL
SEARCH
SECOND
SECOND_MICROSECOND
SECTION
SECURITY
SELECT
SELF
SENSITIVE
SEPARATOR
SEQUENCE
SERIALIZABLE
SERVER_NAME
SESSION
SESSION_USER
SET
SETOF
SETS
SETUSER
SHARE
SHOW
SHUTDOWN
SIGNAL
SIMILAR
SIMPLE
SIZE
SMALLINT
SOME
SONAME
SOURCE
SPACE
SPATIAL
SPECIFIC
SPECIFIC_NAME
SPECIFICTYPE
SQL
SQL_BIG_RESULT
SQL_BIG_SELECTS
SQL_BIG_TABLES
SQL_CALC_FOUND_ROWS
SQL_LOG_OFF
SQL_LOG_UPDATE
SQL_LOW_PRIORITY_UPDATES
SQL_SELECT_LIMIT
SQL_SMALL_RESULT
SQL_WARNINGS
SQLCA
SQLCODE
SQLERROR
SQLEXCEPTION
SQLSTATE
SQLWARNING
SQRT
SSL
STABLE
START
STARTING
STATE
STATEMENT
STATIC
STATISTICS
STATUS
STDDEV_POP
STDDEV_SAMP
STDIN
STDOUT
STORAGE
STRAIGHT_JOIN
STRICT
STRING
STRUCTURE
STYLE
SUBCLASS_ORIGIN
SUBLIST
SUBMULTISET
SUBSTRING
SUCCESSFUL
SUM
SUPERUSER
SYMMETRIC
SYNONYM
SYSDATE
SYSID
SYSTEM
SYSTEM_USER
TABLE
TABLE_NAME
TABLES
TABLESAMPLE
TABLESPACE
TEMP
TEMPLATE
TEMPORARY
TERMINATE
TERMINATED
TEXT
TEXTSIZE
THAN
THEN
TIES
TIME
TIMESTAMP
TIMEZONE_HOUR
TIMEZONE_MINUTE
TINYBLOB
TINYINT
TINYTEXT
TO
TOAST
TOP
TOP_LEVEL_COUNT
TRAILING
TRAN
TRANSACTION
TRANSACTION_ACTIVE
TRANSACTIONS_COMMITTED
TRANSACTIONS_ROLLED_BACK
TRANSFORM
TRANSFORMS
TRANSLATE
TRANSLATION
TREAT
TRIGGER
TRIGGER_CATALOG
TRIGGER_NAME
TRIGGER_SCHEMA
TRIM
TRUE
TRUNCATE
TRUSTED
TSEQUAL
TYPE
UESCAPE
UID
UNBOUNDED
UNCOMMITTED
UNDER
UNDO
UNENCRYPTED
UNION
UNIQUE
UNKNOWN
UNLISTEN
UNLOCK
UNNAMED
UNNEST
UNSIGNED
UNTIL
UPDATE
UPDATETEXT
UPPER
USAGE
USE
USER
USER_DEFINED_TYPE_CATALOG
USER_DEFINED_TYPE_CODE
USER_DEFINED_TYPE_NAME
USER_DEFINED_TYPE_SCHEMA
USING
UTC_DATE
UTC_TIME
UTC_TIMESTAMP
VACUUM
VALID
VALIDATE
VALIDATOR
VALUE
VALUES
VAR_POP
VAR_SAMP
VARBINARY
VARCHAR
VARCHAR2
VARCHARACTER
VARIABLE
VARIABLES
VARYING
VERBOSE
VIEW
VOLATILE
WAITFOR
WHEN
WHENEVER
WHERE
WHILE
WIDTH_BUCKET
WINDOW
WITH
WITHIN
WITHOUT
WORK
WRITE
WRITETEXT
X509
XOR
YEAR
YEAR_MONTH
ZEROFILL
ZONE