每个字符串文字都有一个字符集和一个排序规则。
对于简单的语句 SELECT '
,字符串具有由 字符串
'character_set_connection
和 collation_connection
系统变量定义的连接默认字符集和排序规则。
字符串文字可以有一个可选的字符集引导符和 COLLATE
子句,以将其指定为使用特定字符集和排序规则的字符串。
[_charset_name]'string' [COLLATE collation_name]
_
表达式正式称为引导符。它告诉解析器,““后面的字符串使用字符集 charset_name
charset_name
。” 引导符不会像 CONVERT()
那样将字符串更改为引导符字符集。它不会更改字符串值,但可能会发生填充。引导符只是一个信号。请参阅第 12.3.8 节“字符集引导符”。
示例
SELECT 'abc';
SELECT _latin1'abc';
SELECT _binary'abc';
SELECT _utf8mb4'abc' COLLATE utf8mb4_danish_ci;
字符集引导符和 COLLATE
子句的实现符合标准 SQL 规范。
MySQL 按以下方式确定字符串文字的字符集和排序规则:
如果同时指定了
_charset_name
和COLLATE
,则使用字符集collation_name
charset_name
和排序规则collation_name
。collation_name
必须是charset_name
允许的排序规则。如果指定了
_charset_name
但未指定COLLATE
,则使用字符集charset_name
及其默认排序规则。要查看每个字符集的默认排序规则,请使用SHOW CHARACTER SET
语句或查询INFORMATION_SCHEMA
CHARACTER_SETS
表。如果未指定
_charset_name
但指定了COLLATE
,则使用由collation_name
character_set_connection
系统变量给出的连接默认字符集和排序规则collation_name
。collation_name
必须是连接默认字符集允许的排序规则。否则(既未指定
_charset_name
也未指定COLLATE
),则使用由collation_name
character_set_connection
和collation_connection
系统变量给出的连接默认字符集和排序规则。
示例
具有
latin1
字符集和latin1_german1_ci
排序规则的非二进制字符串SELECT _latin1'Müller' COLLATE latin1_german1_ci;
具有
utf8mb4
字符集及其默认排序规则(即utf8mb4_0900_ai_ci
)的非二进制字符串SELECT _utf8mb4'Müller';
具有
binary
字符集及其默认排序规则(即binary
)的二进制字符串SELECT _binary'Müller';
具有连接默认字符集和
utf8mb4_0900_ai_ci
排序规则的非二进制字符串(如果连接字符集不是utf8mb4
,则失败)SELECT 'Müller' COLLATE utf8mb4_0900_ai_ci;
具有连接默认字符集和排序规则的字符串
SELECT 'Müller';
引导符指示后面字符串的字符集,但不会更改解析器在字符串中执行转义处理的方式。解析器始终根据 character_set_connection
给出的字符集来解释转义字符。
以下示例显示,即使存在引导符,转义处理也会使用 character_set_connection
进行。这些示例使用 SET NAMES
(它会更改 character_set_connection
,如第 12.4 节“连接字符集和排序规则”中所述),并使用 HEX()
函数显示结果字符串,以便可以看到确切的字符串内容。
示例 1
mysql> SET NAMES latin1;
mysql> SELECT HEX('à\n'), HEX(_sjis'à\n');
+------------+-----------------+
| HEX('à\n') | HEX(_sjis'à\n') |
+------------+-----------------+
| E00A | E00A |
+------------+-----------------+
这里,à
(十六进制值 E0
)后面是 \n
,即换行符的转义序列。转义序列使用 character_set_connection
值 latin1
进行解释,以生成文字换行符(十六进制值 0A
)。即使对于第二个字符串也会发生这种情况。也就是说,_sjis
引导符不会影响解析器的转义处理。
示例 2
mysql> SET NAMES sjis;
mysql> SELECT HEX('à\n'), HEX(_latin1'à\n');
+------------+-------------------+
| HEX('à\n') | HEX(_latin1'à\n') |
+------------+-------------------+
| E05C6E | E05C6E |
+------------+-------------------+
这里,character_set_connection
为 sjis
,这是一种字符集,其中 à
后跟 \
的序列(十六进制值 05
和 5C
)是一个有效的多字节字符。因此,字符串的前两个字节被解释为一个 sjis
字符,而 \
不被解释为转义字符。后面的 n
(十六进制值 6E
)不被解释为转义序列的一部分。即使对于第二个字符串也是如此;_latin1
引导符不会影响转义处理。