Collation 差异导致 KingbaseES 与 Oracle 查询结果不同
问题引入
前端提了个问题,说是KingbaseES 返回的结果与 Oracle 返回的结果不一样。具体问题如下:
oracle 执行结果:oracle 有结果返回。
SQL> create table t3(id varchar(9)); Table created. SQL>insert into t3 values('abcd'); 1 row created. SQL>select * from t3 where id<='abc~'; ID --------- abcd
KingbaseES 执行结果:无结果返回
test=# create table t3(id varchar(9)); CREATE TABLE test=# insert into t3 values('abcd'); INSERT 0 1 test=# select * from t3 where id<='abc~'; id ---- (0 rows)
问题分析
查看数据库排序规则
test=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+--------+----------+-------------+-------------+------------------- security | system | UTF8 | en_US.UTF-8 | en_US.UTF-8 | template0 | system | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/system + | | | | | system=CTc/system template1 | system | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/system + | | | | | system=CTc/system test | system | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
尝试用 collate "c" 验证
test=# select * from t3 where id<='abc~' collate "C"; id ------ abcd (1 row)
问题结论
1、oracle 默认 collation binary (可以看 dba_users.DEFAULT_COLLATION = 'USING_NLS_COMP' ,也就是参照nls_database_parameters.NLS_SORT 的值),二进制的排序可能并不适用于语言的规则。
2、KingbaseES 默认使用语言的规则进行排序,如果要使用二进制排序,可以使用 “C” or "POSIX"
最后再看个差异的例子:
oracle 二进制排序:
SQL> select * from t3 order by 1; ID --------- MacDonald MacIntosh Macdonald Macintosh
KingbaseES en_US.UTF-8 排序
test=# select * from t3 order by 1; id ----------- Macdonald MacDonald Macintosh MacIntosh test=# select * from t3 order by id collate "C"; id ----------- MacDonald MacIntosh Macdonald Macintosh
KINGBASE研究院