文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


12.2.1 字符集指令表

字符集的指令表是该字符集中字符的集合。

字符串表达式具有指令表属性,该属性可以有两个值:

  • ASCII:表达式只能包含 ASCII 字符;也就是说,Unicode 范围 U+0000U+007F 中的字符。

  • UNICODE:表达式可以包含 Unicode 范围 U+0000U+10FFFF 中的字符。这包括基本多语言平面 (BMP) 范围 (U+0000U+FFFF) 中的字符和 BMP 范围外的补充字符 (U+10000U+10FFFF)。

ASCII 范围是 UNICODE 范围的子集,因此具有 ASCII 指令表的字符串可以安全地转换为具有 UNICODE 指令表的任何字符串的字符集,而不会丢失信息。它也可以安全地转换为 ascii 字符集的任何超集。(所有 MySQL 字符集都是 ascii 的超集,但 swe7 除外,它将一些标点字符重新用于瑞典语重音字符。)

在许多情况下,指令表的使用可以在表达式中进行字符集转换,否则 MySQL 会在排序规则强制性规则不足以解决歧义时返回 排序规则混合非法 错误。(有关强制性的信息,请参阅 第 12.8.4 节“表达式中的排序规则强制性”。)

以下讨论提供了表达式及其指令表的示例,并描述了指令表的使用如何改变字符串表达式求值:

  • 字符串常量的指令表取决于字符串内容,并且可能与字符串字符集的指令表不同。请考虑以下语句:

    SET NAMES utf8mb4; SELECT 'abc';
    SELECT _utf8mb4'def';

    尽管在上述每种情况下字符集都是 utf8mb4,但字符串实际上并不包含 ASCII 范围外的任何字符,因此它们的指令表是 ASCII 而不是 UNICODE

  • 具有 ascii 字符集的列由于其字符集而具有 ASCII 指令表。在下表中,c1 具有 ASCII 指令表:

    CREATE TABLE t1 (c1 CHAR(1) CHARACTER SET ascii);

    以下示例说明了在没有指令表的情况下发生错误时,指令表如何能够确定结果:

    CREATE TABLE t1 (
      c1 CHAR(1) CHARACTER SET latin1,
      c2 CHAR(1) CHARACTER SET ascii
    );
    INSERT INTO t1 VALUES ('a','b');
    SELECT CONCAT(c1,c2) FROM t1;

    如果没有指令表,则会发生此错误:

    ERROR 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT)
    and (ascii_general_ci,IMPLICIT) for operation 'concat'

    使用指令表,可以进行子集到超集(asciilatin1)转换,并返回结果:

    +---------------+
    | CONCAT(c1,c2) |
    +---------------+
    | ab            |
    +---------------+
  • 具有一个字符串参数的函数继承其参数的指令表。UPPER(_utf8mb4'abc') 的结果具有 ASCII 指令表,因为其参数具有 ASCII 指令表。(尽管有 _utf8mb4 引导符,但字符串 'abc' 不包含 ASCII 范围外的任何字符。)

  • 对于返回字符串但不具有字符串参数并使用 character_set_connection 作为结果字符集的函数,如果 character_set_connectionascii,则结果指令表为 ASCII,否则为 UNICODE

    FORMAT(numeric_column, 4);

    指令表的使用改变了 MySQL 对以下示例的求值方式:

    SET NAMES ascii;
    CREATE TABLE t1 (a INT, b VARCHAR(10) CHARACTER SET latin1);
    INSERT INTO t1 VALUES (1,'b');
    SELECT CONCAT(FORMAT(a, 4), b) FROM t1;

    如果没有指令表,则会发生此错误:

    ERROR 1267 (HY000): Illegal mix of collations (ascii_general_ci,COERCIBLE)
    and (latin1_swedish_ci,IMPLICIT) for operation 'concat'

    使用指令表,会返回结果:

    +-------------------------+
    | CONCAT(FORMAT(a, 4), b) |
    +-------------------------+
    | 1.0000b                 |
    +-------------------------+
  • 具有两个或多个字符串参数的函数对结果指令表使用 最宽 参数指令表,其中 UNICODEASCII 宽。请考虑以下 CONCAT() 调用:

    CONCAT(_ucs2 X'0041', _ucs2 X'0042')
    CONCAT(_ucs2 X'0041', _ucs2 X'00C2')

    对于第一个调用,指令表是 ASCII,因为两个参数都在 ASCII 范围内。对于第二个调用,指令表是 UNICODE,因为第二个参数在 ASCII 范围之外。

  • 函数返回值的指令表是根据仅影响结果字符集和排序规则的那些参数的指令表确定的。

    IF(column1 < column2, 'smaller', 'greater')

    结果指令表是 ASCII,因为两个字符串参数(第二个参数和第三个参数)都具有 ASCII 指令表。第一个参数对结果指令表无关紧要,即使表达式使用字符串值也是如此。