字符集的 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
字符集的列具有ASCII
répertoire,因为它的字符集。在以下表中,c1
具有ASCII
ré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')
的结果具有ASCII
repertoire,因为其参数具有ASCII
repertoire。(尽管有_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
,因为两个字符串参数(第二个参数和第三个参数)都具有ASCII
repertoire。第一个参数不影响结果repertoire,即使表达式使用字符串值。