字符集和字符序合并规则
在B兼容模式(即sql_compatibility = 'B')的数据库下,且设置参数b_format_version='5.7'和b_format_dev_version='s2'时,可以将不同字符集字符序的表达式按一定优先级处理,来确定字符串比较运算时的使用的字符序和表达式的字符集。
字符序优先级
不同表达式字符序优先级由高到低排列如下:
当两个表达式字符序不同时,使用字符序优先级最高的表达式的字符序。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
gaussdb=# CREATE TABLE t_utf8(c1 varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin); gaussdb=# INSERT INTO t_utf8 VALUES('STRING'); -- 比较时使用utf8mb4_bin字符序,结果为false。 gaussdb=# SELECT c1 = 'string' AS result FROM t_utf8; result -------- f (1 row) -- 比较时使用utf8mb4_general_ci字符序,结果为true。 gaussdb=# SELECT c1 = 'string' COLLATE utf8mb4_general_ci AS result FROM t_utf8; result -------- t (1 row) -- 将绑定参数“$1”的字符序定义为collation_connection。 gaussdb=# PREPARE test_collation(text) AS SELECT c1 = $1 AS result FROM t_utf8; -- 绑定参数字符序与字符串常量同级别,即使传入的表达式含有显式的字符序,比较时仍然采用c1的字符序。 gaussdb=# EXECUTE test_collation('string' COLLATE utf8mb4_general_ci); result -------- f (1 row) -- CASE表达式与c1列同级别,即使表达式含有显式的字符序,比较时仍然采用c1的字符序,二者不相等,输出“same level”。 gaussdb=# SELECT CASE 'string' COLLATE utf8mb4_general_ci WHEN c1 THEN 'different level' ELSE 'same level' END AS result FROM t_utf8; result ------------ same level (1 row) -- IN子查询与c1列同级别,即使表达式含有显式的字符序,比较时仍然采用c1的字符序,二者不相等。 gaussdb=# SELECT c1 FROM t_utf8 WHERE c1 in (SELECT 'string' COLLATE utf8mb4_general_ci); c1 ---- (0 rows) |
当两个相同优先级的表达式字符序不同时,采用以下方式处理:
- 如果两者字符集相同,优先使用后缀为_bin的字符序。
- 如果两者字符集相同,优先不使用default字符序。
- 如果不符合上述情况,两表达式将被标记为字符序冲突,字符序将被标记为无效。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
gaussdb=# CREATE TABLE t_utf8mb4_charset( c_utf8_bin varchar(16) character set utf8mb4 collate utf8mb4_bin, c_utf8_uni varchar(16) character set utf8mb4 collate utf8mb4_unicode_ci, c_utf8_gen varchar(16) character set utf8mb4 collate utf8mb4_general_ci); gaussdb=# INSERT INTO t_utf8mb4_charset VALUES('STRING', 'String', 'string'); -- 优先使用utf8mb4_bin字符序比较,结果为false。 gaussdb=# SELECT c_utf8_bin = c_utf8_uni FROM t_utf8mb4_charset; -- 字符序冲突,进行二进制比较,结果为false。 gaussdb=# SELECT c_utf8_uni = c_utf8_gen FROM t_utf8mb4_charset; -- 显式指定的字符序冲突,抛出异常。 gaussdb=# SELECT c_utf8_uni COLLATE utf8mb4_unicode_ci = c_utf8_gen COLLATE utf8mb4_general_ci FROM t_utf8mb4_charset; |