每个字符串文字都有一个字符集和一个排序规则。
对于简单语句SELECT'string',字符串具有由character set_connection和collation_connection系统变量定义的连接默认字符集和排序规则。
字符串文字可能具有可选的字符集介绍程序和COLLATE子句,以将其指定为使用特定字符集和排序规则的字符串:
[_charset_name]'string' [COLLATE collation_name]
_charset_name 表达式正式称为 介绍者。它告诉解析器,“后面的字符串使用字符集字符集名称。”介绍人不会像CONVERT()那样将字符串更改为介绍人字符集。它不会更改字符串值,尽管可能会出现填充。
例子:
SELECT 'abc';
SELECT _latin1'abc';
SELECT _binary'abc';
SELECT _utf8mb4'abc' COLLATE utf8mb4_danish_ci;
字符集介绍程序和COLLATE 子句是根据标准SQL规范实现的。
MySQL通过以下方式确定字符集和字符串文字的排序规则:
1、如果同时指定了字符集名称和排序规则名称,则使用字符集字符集名称和排序规则名称。排序规则名称必须是字符集名称允许的排序规则。
2、如果指定了字符集名称但未指定排序规则,则使用字符集字符集名称及其默认排序规则。若要查看每个字符集的默认排序规则,请使用SHOW character set语句或查询信息架构字符集表。
3、如果未指定字符集名称,但指定了排序规则名称,则使用字符集连接系统变量给定的连接默认字符集和排序规则名称。排序规则名称必须是连接默认字符集允许的排序规则。
4、否则(既不指定字符集名称也不指定排序规则名称),将使用由字符集连接和排序规则连接系统变量给定的连接默认字符集和排序规则。
例子:
具有latin1字符集和latin1_german1_ci排序规则的非二进制字符串:
SELECT _latin1'Müller' COLLATE latin1_german1_ci;
具有utf8mb4字符集及其默认排序规则(即 utf8mb4_general_ci)的非二进制字符串:
SELECT _utf8mb4'Müller';
具有binary字符集及其默认排序规则(即 binary)的二进制字符串:
SELECT _binary'Müller';
具有连接默认字符集和utf8mb4_general_ci排序规则的非二进制字符串(如果连接字符集不是,则失败 utf8mb4):
SELECT 'Müller' COLLATE utf8mb4_general_ci;
具有连接默认字符集和排序规则的字符串:
SELECT 'Müller';
引入程序指示以下字符串的字符集,但不更改解析器在字符串内执行转义处理的方式。解析器始终根据给出的字符集来解释转义 character_set_connection。
以下示例显示,character_set_connection即使在引入器存在的情况下,也会使用Escape进行转义处理 。这些示例使用 SET NAMES(character_set_connection如第10.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引导不影响转义处理。