
# 字符集和字符序合并规则
不同字符集字符序的表达式按一定优先级处理，来确定字符串比较运算时的使用的字符序和表达式的字符集。
#### 字符序优先级
**不同表达式字符序优先级由高到低排列如下：**
- COLLATE语法拥有最高优先级。
  
- 含有字符序冲突的表达式（如：两个不同字符序的字符串拼接表达式）。
  
- 支持字符序的数据类型的列、用户自定义变量、存储过程参数以及CASE表达式等。
  
- 特定的系统函数（如：version()和opengauss_version()函数表达式）。
  
- 字符串常量和绑定参数。
  
- NULL表达式。
  
- 一个表达式的数据类型不支持字符序，这个表达式拥有最低优先级。
  
 
**当两个表达式字符序不同时，使用字符序优先级最高的表达式的字符序。**
示例：
```
m_db=# CREATE TABLE t_utf8(c1 varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin);
m_db=# INSERT INTO t_utf8 VALUES('STRING');
-- 比较时使用utf8mb4_bin字符序，结果为false。
m_db=#  SELECT c1 = 'string' AS result FROM t_utf8;
 result
--------
 f
(1 row)
-- 比较时使用utf8mb4_general_ci字符序，结果为true。
m_db=# SELECT c1 = 'string' COLLATE utf8mb4_general_ci AS result FROM t_utf8;
 result
--------
 t
(1 row)
-- CASE表达式与c1列同级别，即使表达式含有显式的字符序，比较时仍然采用c1的字符序，二者不相等，输出“same level”。
m_db=# 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的字符序，二者不相等。
m_db=# SELECT c1 FROM t_utf8 WHERE c1 in (SELECT 'string' COLLATE utf8mb4_general_ci);
 c1
----
(0 rows)
-- 删除表
m_db=# DROP TABLE t_utf8;
```
**当两个相同优先级的表达式字符序不同时，采用以下方式处理：**
- 如果两者字符集相同，优先使用后缀为_bin的字符序。
- 如果两者字符集相同，优先不使用default字符序。
- 如果不符合上述情况，两表达式将被标记为字符序冲突，字符序将被标记为无效。
  - 因COLLATE语法指定同字符集不同字符序产生的冲突，将提示异常。
    
  
  - 若冲突的两个字符序均为M-Compatibility下支持的字符序，将提示异常。
  
  - 无效字符序如果被用作排序运算时（如：\>、\<等），将提示异常。
  
  - 字符串等值比较时，如果字符序无效，将直接作为二进制比较相等。
   
示例：
```
m_db=# 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);
m_db=# INSERT INTO t_utf8mb4_charset VALUES('STRING', 'String', 'string');
-- 优先使用utf8mb4_bin字符序比较，结果为false。
m_db=# SELECT c_utf8_bin = c_utf8_uni FROM t_utf8mb4_charset;
 ?column?
----------
 f
(1 row)
-- 字符序冲突，提示异常。
m_db=# SELECT c_utf8_uni = c_utf8_gen FROM t_utf8mb4_charset;
ERROR:  Collation mismatch between collations "utf8mb4_unicode_ci" and "utf8mb4_general_ci".
LINE 1: SELECT c_utf8_uni = c_utf8_gen FROM t_utf8mb4_charset;
                            ^
-- 显式指定的字符序冲突，提示异常。
m_db=# SELECT c_utf8_uni COLLATE utf8mb4_unicode_ci = c_utf8_gen COLLATE utf8mb4_general_ci FROM t_utf8mb4_charset;
ERROR:  collation mismatch between explicit collations "utf8mb4_unicode_ci" and "utf8mb4_general_ci"
LINE 1: ..._utf8_uni COLLATE utf8mb4_unicode_ci = c_utf8_gen COLLATE ut...
                                                             ^
-- 删除表
m_db=# DROP TABLE t_utf8mb4_charset;
```
![](https://support.huaweicloud.com/distributed-m-comp-devg-v8-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
- 只有字符串类型（不包括"char"、name）的对象和表达式的字符集可以和数据库的字符集不同。
  
- 在字符集和字符序合并规则中，认为 C、POSIX和DEFAULT字符序对应的字符集为server_encoding。
 
