10.3.6 字符串 Literals 字符集和排序规则
每个字符串 Literals 都有一个字符集和一个排序规则。
对于简单语句SELECT 'string'
,该字符串具有由character_set_connection和collation_connection系统变量定义的连接默认字符集和排序规则。
字符串 Literals 可能具有可选的字符集介绍人和COLLATE
子句,以将其指定为使用特定字符集和排序规则的字符串:
[_charset_name]'string' [COLLATE collation_name]
_charset_name
table 达式正式称为* introducer 。它告诉解析器,“后面的字符串使用字符集 charset_name
*。”引入程序不会像CONVERT()那样将字符串更改为引入程序字符集。尽管可能会发生填充,但它不会更改字符串值。引入器只是一个 signal。参见第 10.3.8 节“字符集介绍者”。
Examples:
SELECT 'abc';
SELECT _latin1'abc';
SELECT _binary'abc';
SELECT _utf8'abc' COLLATE utf8_danish_ci;
字符集介绍程序和COLLATE
子句是根据标准 SQL 规范实现的。
MySQL 通过以下方式确定字符集和字符串 Literals 的排序规则:
-
如果同时指定了*
_charset_name
和COLLATE collation_name
,则使用字符集charset_name
和排序规则collation_name
*。 *collation_name
必须是charset_name
*的允许排序规则。 -
如果指定*
_charset_name
但未指定COLLATE
,则使用字符集charset_name
*及其默认归类。要查看每个字符集的默认排序规则,请使用显示字符集语句或查询INFORMATION_SCHEMA
CHARACTER_SETStable。 -
如果未指定*
_charset_name
但已指定COLLATE collation_name
,则使用character_set_connection系统变量和归类collation_name
*给出的连接默认字符集。 *collation_name
*必须是连接默认字符集允许的归类。 -
否则(既未指定*
_charset_name
*也未指定COLLATE collation_name
),将使用character_set_connection和collation_connection系统变量给出的连接默认字符集和排序规则。
Examples:
- 具有
latin1
字符集和latin1_german1_ci
归类的非二进制字符串:
SELECT _latin1'Müller' COLLATE latin1_german1_ci;
- 具有
utf8
字符集及其默认排序规则(即utf8_general_ci
)的非二进制字符串:
SELECT _utf8'Müller';
- 具有
binary
字符集和默认排序规则(即binary
)的二进制字符串:
SELECT _binary'Müller';
- 具有连接默认字符集和
utf8_general_ci
排序规则的非二进制字符串(如果连接字符集不是utf8
,则失败):
SELECT 'Müller' COLLATE utf8_general_ci;
- 具有连接默认字符集和排序规则的字符串:
SELECT 'Müller';
引入程序指示以下字符串的字符集,但不更改解析器在字符串内执行转义处理的方式。解析器始终根据character_set_connection给出的字符集来解释转义。
以下示例显示,即使存在引入程序,也使用character_set_connection进行转义处理。这些示例使用SET NAMES(如第 10.4 节“连接字符集和排序规则”中所述,将更改character_set_connection),并使用HEX()函数显示结果字符串,以便可以看到确切的字符串内容。
Example 1:
mysql> SET NAMES latin1;
mysql> SELECT HEX('à\n'), HEX(_sjis'à\n');
+------------+-----------------+
| HEX('à\n') | HEX(_sjis'à\n') |
+------------+-----------------+
| E00A | E00A |
+------------+-----------------+
在此,__(十六进制值E0
)后跟\n
(换行符的转义序列)。使用latin1
的character_set_connection值解释转义序列以产生 Literals 换行符(十六进制值0A
)。即使对于第二个字符串,也会发生这种情况。也就是说,_sjis
引入程序不会影响解析器的转义处理。
Example 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
简介不会影响转义处理。