【数据库】关于SQL SERVER的排序规则的问题分析

在安装报表系统,运行sql语句时候提示“无法解决 equal to 操作的排序规则冲突。”,费了半天时间才搞定,原来是因为sql语句中没有加全collate Chinese_PRC_CI_AI_WS !

用排序规则特点计算汉字笔划和取得拼音首字母 

  SQL SERVER的排序规则平时使用不是很多,也许不少初学者还比较陌生,但有 
一个错误大家应是经常碰到: SQL SERVER数据库,在跨库多表连接查询时,若两数据 
库默认字符集不同,系统就会返回这样的错误: 

“无法解决 equal to 操作的排序规则冲突。” 

一.错误分析


  这个错误是因为排序规则不一致造成的,我们做个测试,比如: 
create table #t1( 
name varchar(20) collate Albanian_CI_AI_WS, 
value int) 

create table #t2( 
name varchar(20) collate Chinese_PRC_CI_AI_WS, 
value int ) 

表建好后,执行连接查询: 

select * from #t1 A inner join #t2 B on A.name=B.name 

这样,错误就出现了: 

服务器: 消息 446,级别 16,状态 9,行 1 
无法解决 equal to 操作的排序规则冲突。 
  要排除这个错误,最简单方法是,表连接时指定它的排序规则,这样错误就 
不再出现了。语句这样写: 

select * 
from #t1 A inner join #t2 B 
on A.name=B.name collate Chinese_PRC_CI_AI_WS 


二.排序规则简介

什么叫排序规则呢?MS是这样描述的:"在 Microsoft SQL Server 2000 中, 
字符串的物理存储由排序规则控制。排序规则指定表示每个字符的位模式以及存 
储和比较字符所使用的规则。" 
  在查询分析器内执行下面语句,可以得到SQL SERVER支持的所有排序规则。 

    select * from ::fn_helpcollations() 

排序规则名称由两部份构成,前半部份是指本排序规则所支持的字符集。 
如: 
  Chinese_PRC_CS_AI_WS 
前半部份:指UNICODE字符集,Chinese_PRC_指针对大陆简体字UNICODE的排序规则。 
排序规则的后半部份即后缀 含义: 
  _BIN 二进制排序 
  _CI(CS) 是否区分大小写,CI不区分,CS区分 
  _AI(AS) 是否区分重音,AI不区分,AS区分    
  _KI(KS) 是否区分假名类型,KI不区分,KS区分  
_WI(WS) 是否区分宽度 WI不区分,WS区分  

区分大小写:如果想让比较将大写字母和小写字母视为不等,请选择该选项。 
区分重音:如果想让比较将重音和非重音字母视为不等,请选择该选项。如果选择该选项, 
比较还将重音不同的字母视为不等。 
区分假名:如果想让比较将片假名和平假名日语音节视为不等,请选择该选项。 
区分宽度:如果想让比较将半角字符和全角字符视为不等,请选择该选项 


三.排序规则的应用 


  SQL SERVER提供了大量的WINDOWS和SQLSERVER专用的排序规则,但它的应用往往 
被开发人员所忽略。其实它在实践中大有用处。 

  例1:让表NAME列的内容按拼音排序: 

create table #t(id int,name varchar(20)) 
insert #t select 1,'中' 
union all select 2,'国' 
union all select 3,'人' 
union all select 4,'阿' 

select * from #t order by name collate Chinese_PRC_CS_AS_KS_WS 
drop table #t 
/*结果: 
id name 
----------- -------------------- 
4 阿 
2 国 
3 人 
1 中 
*/ 

  例2:让表NAME列的内容按姓氏笔划排序: 

create table #t(id int,name varchar(20)) 

insert #t select 1,'三' 
union all select 2,'乙' 
union all select 3,'二' 
union all select 4,'一' 
union all select 5,'十' 
select * from #t order by name collate Chinese_PRC_Stroke_CS_AS_KS_WS 
drop table #t 
/*结果: 
id name 
----------- -------------------- 
4 一 
2 乙 
3 二 
5 十 
1 三 
*/ 

四.在实践中排序规则应用的扩展 


  SQL SERVER汉字排序规则可以按拼音、笔划等排序,那么我们如何利用这种功能 
来处理汉字的一些难题呢?我现在举个例子: 

          用排序规则的特性计算汉字笔划 

  要计算汉字笔划,我们得先做准备工作,我们知道,WINDOWS多国汉字,UNICODE目前 
收录汉字共20902个。简体GBK码汉字UNICODE值从19968开始。 
  首先,我们先用SQLSERVER方法得到所有汉字,不用字典,我们简单利用SQL语句就 
可以得到: 

select top 20902 code=identity(int,19968,1) into #t from syscolumns a,syscolumns b 

再用以下语句,我们就得到所有汉字,它是按UNICODE值排序的: 

  select code,nchar(code) as CNWord from #t 

  然后,我们用SELECT语句,让它按笔划排序。 

select code,nchar(code) as CNWord 
from #t 
order by nchar(code) collate Chinese_PRC_Stroke_CS_AS_KS_WS,code 

结果: 
code CNWord 
----------- ------ 
19968 一 
20008 丨 
20022 丶 
20031 丿 
20032 乀 
20033 乁 
20057 乙 
20058 乚 
20059 乛 
20101 亅 
19969 丁 
.......... 

  从上面的结果,我们可以清楚的看到,一笔的汉字,code是从19968到20101,从小到大排,但到 
了二笔汉字的第一个字“丁”,CODE为19969,就不按顺序而重新开始了。有了这结果,我们就可以轻 
松的用SQL语句得到每种笔划汉字归类的第一个或最后一个汉字。 
下面用语句得到最后一个汉字: 

create table #t1(id int identity,code int,cnword nvarchar(2)) 

insert #t1(code,cnword) 
select code,nchar(code) as CNWord from #t 
order by nchar(code) collate Chinese_PRC_Stroke_CS_AS_KS_WS,code 


select A.cnword 
from #t1 A 
left join #t1 B on A.id=B.id-1 and A.code<B.code 
where B.code is null 
order by A.id 

得到36个汉字,每个汉字都是每种笔划数按Chinese_PRC_Stroke_CS_AS_KS_WS排序规则排序后的 
最后一个汉字: 

亅阝马风龙齐龟齿鸩龀龛龂龆龈龊龍龠龎龐龑龡龢龝齹龣龥齈龞麷鸞麣龖龗齾齉龘 

  上面可以看出:“亅”是所有一笔汉字排序后的最后一个字,“阝”是所有二笔汉字排序后的最后 
一个字......等等。 
  但同时也发现,从第33个汉字“龗(33笔)”后面的笔划有些乱,不正确。但没关系,比“龗”笔划 
多的只有四个汉字,我们手工加上:齾35笔,齉36笔,靐39笔,龘64笔 

建汉字笔划表(TAB_HZBH): 
create table tab_hzbh(id int identity,cnword nchar(1)) 
--先插入前33个汉字 
insert tab_hzbh 
select top 33 A.cnword 
from #t1 A 
left join #t1 B on A.id=B.id-1 and 
 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
SQL Server排序规则是用于指定数据库中字符数据的排序方式。在安装SQL Server数据库时,默认的排序规则是根据系统区域设置自动生成的。例如,在Windows服务器系统区域设置为英语(美国)时,默认安装的排序规则SQL_Latin1_General_CP1_CI_AS。如果需要修改排序规则,可以按照以下步骤进行操作: 1. 修改表达式排序规则:在SQL查询时,默认排序规则无法覆盖,但可以在查询表达式中指定排序规则进行转换查询。 2. 修改列级排序规则:可以针对特定的列修改排序规则。这可以通过修改列的数据类型或使用ALTER TABLE语句来实现。 3. 修改数据库排序规则:如果需要修改整个数据库排序规则,可以使用ALTER DATABASE语句来更改。在执行ALTER DATABASE之前,需要中断所有对该数据库的访问。 要查看系统中支持的全部排序规则列表,可以使用以下查询: SELECT * FROM ::fn_helpcollations() 要查看当前系统的排序规则,可以使用以下查询: SELECT SERVERPROPERTY('Collation') 要修改数据库排序规则,可以使用以下语法: ALTER DATABASE 数据库名 COLLATE 排序规则名 例如,要将数据库排序规则修改为区分大小写的简体中文排序规则(Chinese_PRC_CS_AS),可以使用以下语句: ALTER DATABASE test COLLATE Chinese_PRC_CS_AS 请注意,在执行ALTER DATABASE之前,需要中断所有对该数据库的访问。 #### 引用[.reference_title] - *1* *2* [SQL sever 排序规则介绍](https://blog.csdn.net/li_jerry/article/details/124845305)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [SQL Server 排序规则](https://blog.csdn.net/E_eric/article/details/9260643)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王伟1982

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值