4.2. 标识符和关键词

上例中的SELECT、UPDATE或VALUES记号是关键词 的例子,即SQL语言中具有特定意义的词。记号MY_TABLE和A则是标识符 的例子。它们标识表、列或者其他数据库对象的名字,取决于使用它们的命令。因此它们有时也被简称为"名字"。关键词和标识符具有相同的词法结构,这意味着我们无法在没有语言知识的前提下区分一个标识符和关键词。一个关键词的完整列表可以在附录 C中找到。

SQL标识符和关键词必须以一个字母(a-z,也可以是带变音符的字母和非拉丁字母)或一个下划线()开始。后续字符可以是字母、下划线()、数字(0-9)或美元符号($)。注意根据SQL标准的字母规定,美元符号是不允许出现在标识符中的,因此它们的使用可能会降低应用的可移植性。SQL标准不会定义包含数字或者以下划线开头或结尾的关键词,因此这种形式的标识符不会与未来可能的标准扩展冲突 。

系统中一个标识符的长度不能超过 NAMEDATALEN-1 字节,在命令中可以写超过此长度的标识符,但是它们会被截断。默认情况下,NAMEDATALEN 的值为64,因此标识符的长度上限为63字节。如果这个限制有问题,可以在src/include/pg_config_manual.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;

受限标识符可以包含任何字符,除了代码为0的字符(如果要包含一个双引号,则写两个双引号)。这使得可以构建原本不被允许的表或列的名称,例如包含空格或花号的名字。但是长度限制依然有效。

一种受限标识符的变体允许包括转义的用代码点标识的Unicode字符。这种变体以U&(大写或小写U跟上一个花号)开始,后面紧跟双引号修饰的名称,两者之间没有任何空白,如U&"foo"(注意这里与操作符&似乎有一些混淆,但是在&操作符周围使用空白避免了这个问题) 。在引号内,Unicode字符可以以转义的形式指定:反斜线接上4位16进制代码点号码或者反斜线和加号接上6位16进制代码点号码。例如,标识符"data"可以写成:U&"d\0061t\+000061"

下面的例子用斯拉夫语字母写出了俄语单词 "slon"(大象):U&"\0441\043B\043E\043D"

如果希望使用其他转义字符来代替反斜线,可以在字符串后使用UESCAPE子句,例如:U&"d!0061t!+000061" UESCAPE '!'

转义字符可以是除了16进制位、加号、单引号、双引号、空白字符之外的任意单个字符。注意转义字符是被写在单引号而不是双引号内。

为了在标识符中包括转义字符本身,将其写两次即可。

Unicode转义语法只有在服务器编码为UTF8时才起效。当使用其他服务器编码时,只有在ASCII范围内(最高到\007F)的编码点才能被使用。4位和6位形式都可以被用来定义UTF-16代理对来组成代码点大于U+FFFF的字符,尽管6位形式的存在使得这种做法变得不必要(代理对并不被直接存储,而是被被绑定到一个单独的代码点然后被编码到UTF-8)。

将一个标识符变得受限同时也使它变成大小写敏感的,反之非受限名称总是被转换成小写形 式。例如,标识符FOO、foo和"foo"在**PostgreSQL中被认为是相同的,而"Foo"和"FOO"则互 不相同且也不同于前面三个标识符(PostgreSQL**将非受限名字转换为小写形式与SQL标准是不兼容 的,SQL标准中要求将非受限名称转换为大写形式。这样根据标准, foo应该和 "FOO"而不是"foo"相同。如果希望写一个可移植的应用,我们应该总是用引号修饰一个特定名字或者 从不使用 引号修饰)。