↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2 / 7.1
历史版本PostgreSQL 7.2 已于 2007 年 2 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

第 1 章 SQL 语法

摘要

本章描述 SQL 的语法。

1.1. 词法结构 #

SQL 输入由一系列命令组成。一个命令由一系列词元组成,并以分号(“;”)终止。输入流的结束也会终止一个命令。哪些词元是合法的,取决于具体命令的语法。

一个词元可以是关键词、标识符、带引号的标识符、字面量(或常量),或者特殊字符符号。词元通常由空白(空格、制表符、换行)分隔,但如果不存在歧义,则不必如此(一般只有特殊字符与其他类型的词元相邻时才会这样)。

此外,注释也可以出现在 SQL 输入中。它们不是词元,实际上等价于空白。

例如,下面是一个(语法上)合法的SQL输入:

SELECT * FROM MY_TABLE;
UPDATE MY_TABLE SET A = 5;
INSERT INTO MY_TABLE VALUES (3, 'hi there');

这是一个由三个命令组成的序列,每行一个命令(虽然这并非必须;一行中可以包含多个命令,命令也可以有意义地跨多行书写)。

在哪些词元标识命令、哪些词元是操作数或参数这一点上,SQL 语法并不十分一致。最前面的几个词元通常是命令名,因此在上面的示例中,我们通常会说是 “SELECT”、“UPDATE” 和 “INSERT” 命令。但是例如 UPDATE 命令总是要求在特定位置出现一个 SET 词元,而这种形式的 INSERT 也要求有一个 VALUES 才算完整。每个命令的精确语法规则见参考手册。

1.1.1. 标识符和关键词 #

上例中的 SELECT、UPDATE 或 VALUES 这类词元都是关键词,也就是在 SQL 语言中具有固定含义的词。词元 MY_TABLE 和 A 则是标识符的例子。它们标识表、列或其他数据库对象的名称,这取决于它们所在的命令。因此,它们有时也简称为“名称”。关键词和标识符具有相同的词法结构,这意味着如果不了解该语言,就无法判断一个词元究竟是标识符还是关键词。完整的关键词列表可以在附录 B中找到。

SQL 标识符和关键词必须以字母(a-z,也包括带变音符的字母和非拉丁字母)或下划线(_)开头。标识符或关键词中的后续字符可以是字母、数字(0-9)或下划线,不过 SQL 标准不会定义包含数字或以下划线开头、结尾的关键词。

系统对标识符最多只使用 NAMEDATALEN-1 个字符;在命令中可以写更长的名称,但它们会被截断。默认情况下, NAMEDATALEN 为 32,因此标识符的最大长度是 31(但在编译系统时,可以修改 src/include/postgres_ext.h 中的 NAMEDATALEN)。

关键词和未加引号的标识符不区分大小写。因此:

UPDATE MY_TABLE SET A = 5;

也可以等价地写成:

uPDaTE my_TabLE SeT a = 5;

一种常见约定是关键词使用大写、名称使用小写,例如:

UPDATE my_table SET a = 5;

还有第二类标识符:定界标识符或带引号的标识符。它通过把任意字符序列括在双引号中形成(")。 定界标识符始终是标识符,绝不会是关键词。因此,"select" 可以用来引用名为 “select” 的列或表,而不加引号的 select 会被视为关键词,因此在期望表名或列名的位置使用时会导致解析错误。这个示例可以用带引号的标识符写成:

UPDATE "my_table" SET "a" = 5;

带引号的标识符可以包含除双引号本身之外的任意字符。这使得可以构造原本不可能的表名或列名,例如包含空格或和号的名称。长度限制仍然适用。

给标识符加上引号也会使其区分大小写,而不加引号的名称总是会被折叠成小写。例如,标识符 FOO、foo 和 "foo" 在 PostgreSQL 中被视为相同,但 "Foo" 和 "FOO" 与这三个都不同,彼此之间也不同。 [2]

1.1.2. 常量 #

在 PostgreSQL 中有四种隐式类型常量:字符串、位串、整数和浮点数。也可以为常量指定显式类型,这样系统就能更准确地表示并更高效地处理它们。隐式常量将在下面介绍;显式常量在随后讨论。

1.1.2.1. 字符串常量 #

SQL 中的字符串常量是由单引号(“'”)括起的任意字符序列,例如 'This is a string'。SQL 允许在字符串中嵌入单引号,方法是写两个相邻的单引号,例如 'Dianne''s horse'。在 PostgreSQL 中,也可以用反斜线(“\”)对单引号转义,例如 'Dianne\'s horse'。

也可以使用 C 风格的反斜线转义:\b 是退格,\f 是换页,\n 是换行,\r 是回车,\t 是制表符,而 \xxx(其中 xxx 是一个八进制数)是具有相应 ASCII 代码的字符。跟随在反斜线后面的任何其他字符都按其字面意思对待。因此,要在字符串常量中包含一个反斜线,请写两个反斜线。

编码为零的字符不能出现在字符串常量中。

两个只由空白及至少一个新行分隔的字符串常量会被连接在一起,并且实际上被当作该字符串写成一个常量来对待。例如:

SELECT 'foo'
'bar';

等同于

SELECT 'foobar';

但是

SELECT 'foo'      'bar';

不是合法的语法,PostgreSQL 在这一点上与 SQL9x 一致。

1.1.2.2. 位串常量 #

位串常量看起来像在常规字符串常量的开引号之前(中间无空白)加了一个 B(大写或小写形式),例如 B'1001'。位串常量中允许的字符只有 0 和 1。位串常量可以以与常规字符串常量相同的方式跨行继续。

1.1.2.3. 整数常量

SQL 中的整数常量是不带小数点也不带指数的十进制数字(0 到 9)序列。合法值的范围取决于所用的整数数据类型,但普通的 integer 类型接受从 -2147483648 到 +2147483647 的值。(可选的正号或负号实际上是一个单独的一元操作符,而不是整数常量的一部分。)

1.1.2.4. 浮点常量

浮点常量接受下列一般形式:

digits.[digits][e[+-]digits]
[digits].digits[e[+-]digits]
digitse[+-]digits

其中 digits 是一个或多个十进制数字。小数点前后必须至少有一位数字。如果存在指数定界符(e),其后必须至少跟随一位数字。这样,浮点常量通过小数点或指数子句(或两者)的存在与整数常量区分开来。常量中不能嵌入空格或其他字符。

这些是合法浮点常量的一些示例:

3.5
4.
.001
5e2
1.925e-3
       

浮点常量的类型是 DOUBLE PRECISION。REAL 可以用 SQL 字符串记法或 PostgreSQL 类型记法显式指定:

REAL '1.23'  -- string style
'1.23'::REAL -- PostgreSQL (historical) style
      

1.1.2.5. 其他类型的常量 #

一个任意类型的常量可以用下列记法之一输入:

type 'string'
'string'::type
CAST ( 'string' AS type )

字符串的文本被传递给名为 type 的类型的输入转换例程。结果就是所指示类型的一个常量。如果常量必须是哪个类型没有歧义(例如,当它作为参数传递给一个未重载的函数时),显式类型转换可以省略,此时它会被自动强制转换。

也可以用类似函数调用的语法来指定类型强制转换:

typename ( 'string' )

但并非所有类型名都可以这样使用;详见 第 1.3.6 节。

::、CAST() 以及函数调用语法也可以用来指定任意表达式的运行时类型转换,如 第 1.3.6 节 中所述。但 type 'string' 形式只能用来指定字面常量的类型。type 'string' 的另一个限制是它不适用于数组类型;要用 :: 或 CAST() 来指定数组常量的类型。

1.1.2.6. 数组常量

数组常量的一般格式如下:

'{ val1 delim val2 delim ... }'

其中 delim 是该类型的分隔符字符,记录在它的 pg_type 项中。(对于所有内建类型,这都是逗号字符 “,”。)每个 val 要么是数组元素类型的一个常量,要么是一个子数组。一个数组常量的示例是

'{{1,2,3},{4,5,6},{7,8,9}}'

这个常量是一个二维的 3×3 数组,由三个整数子数组组成。

单个数组元素可以放在双引号(") 之间,以避免与空白相关的歧义问题。若不加引号,数组值解析器将跳过前导空白。

(数组常量实际上只是前一节讨论的一般类型常量的一种特例。该常量最初被当作字符串处理并被传给数组的输入转换例程。可能需要显式的类型说明。)

1.1.3. 操作符 #

一个操作符是由下列列表中的字符组成的一个序列,长度最多为 NAMEDATALEN-1 个字符(默认是 31):

+ - * / < > = ~ ! @ # % ^ & | ` ? $

不过,操作符名称也有一些限制:

  • $(美元符号)不能作为单字符操作符,但它可以作为多字符操作符名称的一部分。

  • -- 和 /* 不能出现在操作符名称中的任何位置,因为它们会被视为注释的开始。

  • 多字符操作符名称不能以 + 或 - 结尾,除非该名称中还至少包含下列字符中的一个:

    ~ ! @ # % ^ & | ` ? $

    例如,@- 是合法的操作符名称,但 *- 不是。这个限制使 PostgreSQL 能够在不要求词元之间必须有空格的情况下解析符合 SQL 的查询。

当使用非 SQL 标准的操作符名时,你通常需要用空格分隔相邻的操作符来避免歧义。例如,如果你定义了一个名为@的左一元操作符,你不能写X*@Y,你必须写X* @Y来确保PostgreSQL把它读作两个操作符名而不是一个。

1.1.4. 特殊字符

某些非字母数字字符具有不同于操作符的特殊含义。关于它们的详细用法,可以在描述相应语法元素的位置找到。本节只是为了提示它们的存在,并概述这些字符的用途。

  • 美元符号($)后跟数字时,用来表示函数定义体中的位置参数。在其他上下文中,美元符号可以是操作符名称的一部分。

  • 圆括号(())具有它们通常的含义,用来对表达式分组并确定运算优先级。在某些情况中,圆括号被要求作为一个特定 SQL 命令的固定语法的一部分。

  • 方括号([])被用来选择一个数组中的元素。更多关于数组的信息见第 6 章。

  • 逗号(,)被用在某些语法结构中来分割一个列表的元素。

  • 分号(;)结束一个 SQL 命令。它不能出现在一个命令中间的任何位置,除了在一个字符串常量中或者一个带引号的标识符中。

  • 冒号(:)被用来从数组中选择“切片”(见第 6 章)。在某些 SQL 的“方言”(例如嵌入式 SQL)中,冒号被用来作为变量名的前缀。

  • 星号(*)在SELECT命令中或与COUNT聚合函数一起使用时有特殊含义。

  • 句点(.)被用在浮点常量中,并且被用来分割表和列名。

1.1.5. 注释 #

注释是一串以双连字符开始并延伸到行尾的字符,例如:

-- 这是一条标准 SQL92 注释

另外,也可以使用 C 风格注释块:

/* 多行注释
 * 包含嵌套:/* 嵌套块注释 */
 */

这里该注释开始于/*并且延伸到匹配出现的*/。这些注释块可按照 SQL99 中指定的方式嵌套,但和 C 中不同。这样我们可以注释掉一大段可能包含注释块的代码。

在进一步进行语法分析之前,注释会从输入流中移除,并实际被替换为空白。



[2] PostgreSQL 将不加引号的名称折叠为小写,这与 SQL 标准不兼容;标准规定,不加引号的名称应折叠为大写。因此,按照标准, foo 应当等价于 "FOO",而不是 "foo"。如果你想编写可移植的应用,建议对某个特定名称要么始终加引号,要么始终不加引号。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。