字符集的 répertoire 是集合中的字符。
字符串表达式具有 répertoire 属性,该属性可以具有两个值:
-
ASCII:表达式只能包含 ASCII 字符;即 Unicode 范围U+0000到U+007F的字符。 -
UNICODE:表达式可以包含 Unicode 范围U+0000到U+10FFFF的字符。这包括基本多语言平面(BMP)范围(U+0000到U+FFFF)和补充字符范围(U+10000到U+10FFFF)。
ASCII 范围是 UNICODE 范围的子集,因此具有 ASCII répertoire 的字符串可以安全地转换为任何具有 UNICODE répertoire 的字符串的字符集,而不会丢失信息。它也可以安全地转换为任何超集为 ascii 字符集的字符集。(所有 MySQL 字符集都是 ascii 的超集,除了 swe7,它重新使用了一些标点符号来表示瑞典语 accented 字符。)
répertoire 的使用使得在许多情况下可以在表达式中进行字符集转换,而 MySQL 否则将返回一个 “illegal mix of collations” 错误,当 collation 可协调性规则不足以解决歧义时。(有关协调性信息,请参阅 第 12.8.4 节,“表达式中的 Collation Coercibility”。)
以下讨论提供了表达式和它们的 répertoire 的示例,并描述了 répertoire 的使用如何改变字符串表达式的评估:
-
字符串常量的 répertoire 取决于字符串内容,可能与字符串字符集的 répertoire 不同。考虑以下语句:
SET NAMES utf8mb4; SELECT 'abc'; SELECT _utf8mb4'def';尽管每个情况下的字符集都是
utf8mb4,但字符串实际上不包含任何 ASCII 范围之外的字符,因此它们的 répertoire 是ASCII而不是UNICODE。 -
具有
ascii字符集的列具有ASCIIrépertoire,因为它的字符集。在以下表中,c1具有ASCIIrépertoire:CREATE TABLE t1 (c1 CHAR(1) CHARACTER SET ascii);以下示例说明了 répertoire 如何使结果能够在没有 répertoire 时出现错误的情况下确定:
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;如果没有 répertoire,这将出现错误:
ERROR 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (ascii_general_ci,IMPLICIT) for operation 'concat'使用repertoire,从子集到超集(
ascii到latin1)转换可以发生,并返回结果:+---------------+ | CONCAT(c1,c2) | +---------------+ | ab | +---------------+ -
具有一个字符串参数的函数继承其参数的repertoire。例如,
UPPER(_utf8mb4'abc')的结果具有ASCIIrepertoire,因为其参数具有ASCIIrepertoire。(尽管有_utf8mb4引入符,该字符串'abc'不包含ASCII范围之外的字符。) -
对于不带字符串参数且使用
character_set_connection作为结果字符集的函数,结果repertoire 是ASCII如果character_set_connection是ascii,否则为UNICODE:FORMAT(numeric_column, 4);repertoire 的变化如何影响 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;没有repertoire 时,会出现错误:
ERROR 1267 (HY000): Illegal mix of collations (ascii_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation 'concat'有repertoire 时,返回结果:
+-------------------------+ | CONCAT(FORMAT(a, 4), b) | +-------------------------+ | 1.0000b | +-------------------------+ -
具有两个或多个字符串参数的函数使用“最宽”参数repertoire 作为结果repertoire,其中
UNICODE比ASCII宽。考虑以下CONCAT()调用:CONCAT(_ucs2 X'0041', _ucs2 X'0042') CONCAT(_ucs2 X'0041', _ucs2 X'00C2')对于第一个调用,repertoire 是
ASCII,因为两个参数都在 ASCII 范围内。对于第二个调用,repertoire 是UNICODE,因为第二个参数超出 ASCII 范围。 -
函数返回值的repertoire 是根据影响结果字符集和排序的参数的repertoire 确定的。
IF(column1 < column2, 'smaller', 'greater')结果repertoire 是
ASCII,因为两个字符串参数(第二个参数和第三个参数)都具有ASCIIrepertoire。第一个参数不影响结果repertoire,即使表达式使用字符串值。