ORACLE中文排序方式 vs SQL Server 2005的中文排序问题

来源:互联网 发布:勒布朗詹姆斯生涯数据 编辑:程序博客网 时间:2024/05/19 13:08
Oracle9i之前,中文是按照二进制编码进行排序的。 
在oracle9i中新增了按照拼音、部首、笔画排序功能。设置NLS_SORT值 
SCHINESE_RADICAL_M 按照部首(第一顺序)、笔划(第二顺序)排序 
SCHINESE_STROKE_M 按照笔划(第一顺序)、部首(第二顺序)排序 
SCHINESE_PINYIN_M 按照拼音排序 
修改ORACLE字段的默认排序方式
按拼音(默认):  alter session set nls_sort = SCHINESE_PINYIN_M;
按笔画:alter session set nls_sort = SCHINESE_STROKE_M;
按偏旁:alter session set nls_sort = NLS_SORT=SCHINESE_RADICAL_M;

SQL> drop table cc;
表已丢弃。
SQL>  create table cc (b varchar2(20))
表已创建。
SQL>  insert into cc values('一');
已创建 1 行。
SQL> insert into cc values('二');
已创建 1 行。
SQL> insert into cc values('三');
已创建 1 行。
SQL> insert into cc values('四');
已创建 1 行。
SQL> insert into cc values('五');
已创建 1 行。
SQL> insert into cc values('六');
已创建 1 行。
SQL> insert into cc values('七');
已创建 1 行。
SQL>  insert into cc values('八');
已创建 1 行。
SQL> insert into cc values('九');
已创建 1 行。
SQL>  insert into cc values('十');
已创建 1 行。
SQL> select * from cc order by nlssort(b,'NLS_SORT=SCHINESE_PINYIN_M');
说明:按拼音字母(英文字母)排序是ORACLE默认的排序方式,除非已经修改过
B
--------------------










已选择10行。
SQL> select * from cc order by nlssort(b,'NLS_SORT=SCHINESE_STROKE_M');--按笔画
B
--------------------










已选择10行。
SQL>  select * from cc order by nlssort(b,'NLS_SORT=SCHINESE_RADICAL_M');
B
--------------------










已选择10行。

=============================================================

SQL Server 2005的中文排序问题


前天把这个问题研究了一下,原来这个东东里面的水是很深的,远比SQL Server 2000里的中文排序要复杂的多。

起因是这样的,一个字段里有这么些数据:内部对账表、资产负债表、现金流量表、损益表、股东权益分配表、空白报表,等等吧,我用了这样的SQL语句对他们进行的排序:

Select * from BizForm where BizType = ‘4FF8B20F-CEA8-4AFB-A10E-7186EDD4FFAF’ order by FormName ASC;

系统给出的排序结果是这样的:内部对账表、股东权益分配表、空白报表、损益表、现金流量表、资产负债表。它们并不是严格按照中文的拼音顺序排列的, 但是按照上面的查询语句得出的结果就是应该按照中文的拼音顺序排列的呀,难道是SQL Server 2005里的一个BUG?这也太明显了吧,我Update了SP2之后,结果依旧,看来这里面是有名堂的,就去查了SQL Server 2005的联机丛书。

SQL Server 2005的中文排序果然做了升级,默认情况下,其中文排序是这样定义的:

Chinese_PRC_CS_AI_WS 

就是说,使用UNICODE字符集,Chinese_PRC_是针对大陆简体字UNICODE的排序规则;_CI(CS)  是否区分大小写,CI不区分,CS区分;_AI(AS)  是否区分重音,AI不区分,AS区分;_WI(WS)  是否区分宽度  WI不区分,WS区分,所以我要想得到正确的按拼音排序的结果,查询语句就应该是这样写:

Select * from BizForm where BizType = ‘4FF8B20F-CEA8-4AFB-A10E-7186EDD4FFAF’ collate Chinese_PRC_CS_AS_WS;

另外SQL Server 2005还支持按中文笔画来排序,对应的查询语句是:

Select * from BizForm where BizType = ‘4FF8B20F-CEA8-4AFB-A10E-7186EDD4FFAF’ collate Chinese_PRC_Stroke_CS_AS_WS;

但是上面的两种排序规则得出的结果都和我最开始的结果不一样,我再进一步研究才找到答案。其实我使用的ORDER BY语句调用了一个叫二进制排序的方式,二进制排序规则基于区域设置和数据类型所定义的编码值的顺序,对数据进行排序。区域设置就是操作系统里“区域与语 言”里定义的系统所处区域,数据类型是说,对于非Unicode 数据类型,数据比较将基于ANSI 代码页中定义的码位。对于 Unicode 数据类型,数据比较将基于 Unicode 码位。对于 Unicode 数据类型的二进制排序规则,数据排序将不考虑区域设置。这样的话,我用ORDER BY语句得到的结果是按照这些中文在Unicode表里出现的先后顺序排列的,用SQL Server 2005里的新语句应该是这样写的:

Select * from BizForm where BizType = ‘4FF8B20F-CEA8-4AFB-A10E-7186EDD4FFAF’ collate chinese_PRC_bin;

PPS就是按照这样的排序规则把表列传到EXCEL PPS插件里的。

原创粉丝点击