10.2.1 字符集库

字符集的全部是字符集中的字符集合。

字符串 table 达式具有一个曲目属性,该属性可以具有两个值:

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

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

ASCII范围是UNICODE范围的子集,因此具有ASCII曲目的字符串可以安全地转换,而不会丢失任何具有UNICODE曲目的字符串的信息集。也可以将其安全地转换为ascii字符集的超集的任何字符集。 (所有 MySQL 字符集都是ascii的超集,但swe7除外,后者将一些标点符号重用为瑞典的带重音符号的字符.)

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

以下讨论提供了 table 达式及其组成部分的示例,并描述了组成部分的使用如何更改字符串 table 达式求值:

  • 字符串常量的库取决于字符串内容,并且可能与字符串字符集的库不同。考虑以下语句:
SET NAMES utf8; SELECT 'abc';
SELECT _utf8'def';
SELECT N'MySQL';

尽管在上述每种情况下,字符集均为utf8,但这些字符串实际上并不包含 ASCII 范围以外的任何字符,因此它们的字符集为ASCII而不是UNICODE

  • 由于其字符集,具有ascii字符集的列具有ASCII指令库。在下 table 中,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(_utf8'abc')的结果具有ASCII指令库,因为其自变量具有ASCII指令库。 (尽管使用_utf8引入程序,但字符串'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                 |
+-------------------------+
  • 具有两个或多个字符串参数的函数使用“最宽”参数 table 作为结果 table,其中UNICODEASCII宽。考虑以下CONCAT()个调用:
CONCAT(_ucs2 X'0041', _ucs2 X'0042')
CONCAT(_ucs2 X'0041', _ucs2 X'00C2')

对于第一个呼叫,指令集为ASCII,因为两个参数都在 ASCII 范围内。对于第二个调用,由于第二个参数在 ASCII 范围之外,因此指令集为UNICODE

  • 函数返回值的库是根据仅影响结果的字符集和排序规则的那些参数的库确定的。
IF(column1 < column2, 'smaller', 'greater')

结果库为ASCII,因为两个字符串参数(第二个参数和第三个参数)都具有ASCII个库。即使 table 达式使用字符串值,第一个参数对于结果库也不重要。