字符串字面量、十六进制字面量或位值字面量可以有一个可选的字符集指示符和 COLLATE
子句,以将其指定为使用特定字符集和排序规则的字符串。
[_charset_name] literal [COLLATE collation_name]
_
表达式正式称为指示符。它告诉解析器,““后面的字符串使用字符集 charset_name
charset_name
。”指示符不会像 CONVERT()
那样将字符串更改为指示符字符集。它不会更改字符串值,尽管可能会发生填充。指示符只是一个信号。
对于字符串字面量,指示符和字符串之间允许有空格,但不是必需的。
对于字符集字面量,指示符指示后面字符串的字符集,但不会更改解析器在字符串中执行转义处理的方式。解析器始终根据 character_set_connection
给出的字符集来解释转义符。有关其他讨论和示例,请参阅 第 12.3.6 节“字符串字面量字符集和排序规则”。
示例
SELECT 'abc';
SELECT _latin1'abc';
SELECT _binary'abc';
SELECT _utf8mb4'abc' COLLATE utf8mb4_danish_ci;
SELECT _latin1 X'4D7953514C';
SELECT _utf8mb4 0x4D7953514C COLLATE utf8mb4_danish_ci;
SELECT _latin1 b'1000001';
SELECT _utf8mb4 0b1000001 COLLATE utf8mb4_danish_ci;
字符集指示符和 COLLATE
子句是根据标准 SQL 规范实现的。
可以通过使用 _binary
指示符将字符串字面量指定为二进制字符串。十六进制字面量和位值字面量默认情况下是二进制字符串,因此允许使用 _binary
,但通常不需要。在其他情况下将字面量视为数字的情况下,_binary
可能有助于将十六进制或位值字面量保留为二进制字符串。例如,在 MySQL 8.4 及更高版本中,位运算允许使用数字或二进制字符串参数,但默认情况下将十六进制和位值字面量视为数字。要为此类字面量显式指定二进制字符串上下文,请对至少一个参数使用 _binary
指示符。
mysql> SET @v1 = X'000D' | X'0BC0';
mysql> SET @v2 = _binary X'000D' | X'0BC0';
mysql> SELECT HEX(@v1), HEX(@v2);
+----------+----------+
| HEX(@v1) | HEX(@v2) |
+----------+----------+
| BCD | 0BCD |
+----------+----------+
显示的结果对于两个位运算看起来都相似,但是没有 _binary
的结果是 BIGINT
值,而使用 _binary
的结果是二进制字符串。由于结果类型的差异,显示的值也不同:数字结果不显示高阶 0 数字。
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
表。如果指定了
COLLATE
但未指定collation_name
_charset_name
:对于字符串字面量,使用由
character_set_connection
系统变量给出的连接默认字符集和排序规则collation_name
。collation_name
必须是连接默认字符集允许的排序规则。对于十六进制字面量或位值字面量,唯一允许的排序规则是
binary
,因为这些类型的字面量默认情况下是二进制字符串。
否则(既未指定
_charset_name
也未指定COLLATE
):collation_name
对于字符串字面量,使用由
character_set_connection
和collation_connection
系统变量给出的连接默认字符集和排序规则。对于十六进制字面量或位值字面量,字符集和排序规则为
binary
。
示例
具有
latin1
字符集和latin1_german1_ci
排序规则的非二进制字符串SELECT _latin1'Müller' COLLATE latin1_german1_ci; SELECT _latin1 X'0A0D' COLLATE latin1_german1_ci; SELECT _latin1 b'0110' COLLATE latin1_german1_ci;
具有
utf8mb4
字符集及其默认排序规则(即utf8mb4_0900_ai_ci
)的非二进制字符串SELECT _utf8mb4'Müller'; SELECT _utf8mb4 X'0A0D'; SELECT _utf8mb4 b'0110';
具有
binary
字符集及其默认排序规则(即binary
)的二进制字符串SELECT _binary'Müller'; SELECT X'0A0D'; SELECT b'0110';
十六进制字面量和位值字面量不需要指示符,因为它们默认情况下是二进制字符串。
具有连接默认字符集和
utf8mb4_0900_ai_ci
排序规则的非二进制字符串(如果连接字符集不是utf8mb4
,则失败)SELECT 'Müller' COLLATE utf8mb4_0900_ai_ci;
此构造(仅
COLLATE
)不适用于十六进制字面量或位值字面量,因为它们的字符集是binary
,而不管连接字符集是什么,并且binary
与utf8mb4_0900_ai_ci
排序规则不兼容。在没有指示符的情况下,唯一允许的COLLATE
子句是COLLATE binary
。具有连接默认字符集和排序规则的字符串
SELECT 'Müller';