字符集 的指令表是字符集中字符的集合。
字符串表达式有一个 repertoire 属性,它可以有两个值:
ASCII
: 表达式只能包含 ASCII 字符;也就是说,Unicode 范围内的字符U+0000
到U+007F
.UNICODE
: 表达式可以包含 Unicode 范围内的字符U+0000
到U+10FFFF
. 这包括基本多语言平面 (BMP) 范围内的字符 (U+0000
toU+FFFF
) 和 BMP 范围外的补充字符 (U+10000
toU+10FFFF
)。
ASCII
范围是范围的子集
,UNICODE
因此
ASCII
可以将具有指令的字符串安全地转换为任何具有指令的字符串的字符集而不会丢失信息UNICODE
。它还可以安全地转换为作为字符集超集的任何
ascii
字符集。(所有 MySQL 字符集都是 的超集,ascii
除了swe7
,它为瑞典重音字符重用了一些标点符号。)
在许多情况下,使用 repertoire 可以在表达式中进行字符集转换,否则当排序规则可强制性规则不足以解决歧义时 ,MySQL 会返回 “非法排序规则混合”错误。(有关强制性的信息,请参阅 第 10.8.4 节,“表达式中的整理强制性”。)
以下讨论提供了表达式及其指令集的示例,并描述了指令集的使用如何更改字符串表达式评估:
字符串常量的指令表取决于字符串内容,并且可能与字符串字符集的指令表不同。考虑这些陈述:
SET NAMES utf8; SELECT 'abc'; SELECT _utf8'def'; SELECT N'MySQL';
虽然字符集在前面的每一种情况下,但字符串实际上不
utf8
包含 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'
使用曲目,可以发生子集到超集(
ascii
到latin1
)的转换并返回结果:+---------------+ | CONCAT(c1,c2) | +---------------+ | ab | +---------------+
带有一个字符串参数的函数继承了它们参数的全部内容。结果
UPPER(_utf8'abc')
有ASCII
保留曲目,因为它的论证有ASCII
保留曲目。(尽管有_utf8
介绍者,该字符串'abc'
不包含 ASCII 范围之外的字符。)对于返回字符串但没有字符串参数并
character_set_connection
用作结果字符集的函数,结果指令是ASCII
ifcharacter_set_connection
isascii
,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;
没有保留曲目,出现这个错误:
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 | +-------------------------+
具有两个或更多字符串参数的函数使用 “最宽”的参数表作为结果表,其中
UNICODE
比ASCII
. 考虑以下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
曲目。第一个参数对于结果指令集无关紧要,即使表达式使用字符串值也是如此。