10.3.6 字符串 Literals 字符集和排序规则

每个字符串 Literals 都有一个字符集和一个排序规则。

对于简单语句SELECT 'string',该字符串具有由character_set_connectioncollation_connection系统变量定义的连接默认字符集和排序规则。

字符串 Literals 可能具有可选的字符集介绍人和COLLATE子句,以将其指定为使用特定字符集和排序规则的字符串:

[_charset_name]'string' [COLLATE collation_name]

_charset_nametable 达式正式称为* 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_connectioncollation_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(换行符的转义序列)。使用latin1character_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_connectionsjis,是一个字符集,其中à后跟\(十六进制值055C)的序列是有效的多字节字符。因此,字符串的前两个字节被解释为单个sjis字符,而\不被解释为转义字符。以下n(十六进制值6E)不解释为转义序列的一部分。即使对于第二个字符串也是如此。 _latin1简介不会影响转义处理。