文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
信息 (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 范围。第一个参数对结果范围没有影响,即使表达式使用字符串值也是如此。