gpt4 book ai didi

整理一下SQLSERVER的排序规则

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 35 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章整理一下SQLSERVER的排序规则由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

SQL SERVER的排序规则平时使用不是很多,也许不少初学者还比较陌生,但有 。

一个错误大家应是经常碰到:SQLSERVER数据库,在跨库多表连接查询时,若两数据 。

库默认字符集不同,系统就会返回这样的错误:

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

一.错误分析:

这个错误是因为排序规则不一致造成的,我们做个测试,比如:

createtable#t1( 。

namevarchar(20)collateAlbanian_CI_AI_WS.

valueint) 。

createtable#t2( 。

namevarchar(20)collateChinese_PRC_CI_AI_WS.

valueint) 。

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

select*from#t1Ainnerjoin#t2BonA.name=B.name 。

这样,错误就出现了:

服务器:消息446,级别16,状态9,行1 。

无法解决equalto操作的排序规则冲突.

要排除这个错误,最简单方法是,表连接时指定它的排序规则,这样错误就 。

不再出现了。语句这样写:

select* 。

from#t1Ainnerjoin#t2B 。

onA.name=B.namecollateChinese_PRC_CI_AI_WS 。

二.排序规则简介:

什么叫排序规则呢?MS是这样描述的:"在MicrosoftSQLServer2000中, 。

字符串的物理存储由排序规则控制。排序规则指定表示每个字符的位模式以及存 。

储和比较字符所使用的规则。" 。

在查询分析器内执行下面语句,可以得到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区分 。

区分大小写:如果想让比较将大写字母和小写字母视为不等,请选择该选项.

区分重音:如果想让比较将重音和非重音字母视为不等,请选择该选项。如果选择该选项, 。

比较还将重音不同的字母视为不等.

区分假名:如果想让比较将片假名和平假名日语音节视为不等,请选择该选项.

区分宽度:如果想让比较将半角字符和全角字符视为不等,请选择该选项 。

三.排序规则的应用:

SQLSERVER提供了大量的WINDOWS和SQLSERVER专用的排序规则,但它的应用往往 。

被开发人员所忽略。其实它在实践中大有用处.

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

createtable#t(idint,namevarchar(20)) 。

insert#tselect1,'中' 。

unionallselect2,'国' 。

unionallselect3,'人' 。

unionallselect4,'阿' 。

select*from#torderbynamecollateChinese_PRC_CS_AS_KS_WS 。

droptable#t 。

/*结果:

idname 。

------------------------------- 。

4阿 。

2国 。

3人 。

1中 。

*/ 。

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

createtable#t(idint,namevarchar(20)) 。

insert#tselect1,'三' 。

unionallselect2,'乙' 。

unionallselect3,'二' 。

unionallselect4,'一' 。

unionallselect5,'十' 。

select*from#torderbynamecollateChinese_PRC_Stroke_CS_AS_KS_WS 。

droptable#t 。

/*结果:

idname 。

------------------------------- 。

4一 。

2乙 。

3二 。

5十 。

1三 。

*/ 。

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

SQLSERVER汉字排序规则可以按拼音、笔划等排序,那么我们如何利用这种功能 。

来处理汉字的一些难题呢?我现在举个例子:

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

要计算汉字笔划,我们得先做准备工作,我们知道,WINDOWS多国汉字,UNICODE目前 。

收录汉字共20902个。简体GBK码汉字UNICODE值从19968开始.

首先,我们先用SQLSERVER方法得到所有汉字,不用字典,我们简单利用SQL语句就 。

可以得到:

selecttop20902code=identity(int,19968,1)into#tfromsyscolumnsa,syscolumnsb 。

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

selectcode,nchar(code)asCNWordfrom#t 。

然后,我们用Select语句,让它按笔划排序.

selectcode,nchar(code)asCNWord 。

from#t 。

orderbynchar(code)collateChinese_PRC_Stroke_CS_AS_KS_WS,code 。

结果:

codeCNWord 。

----------------- 。

19968一 。

20008丨 。

20022丶 。

20031丿 。

20032乀 。

20033乁 。

20057乙 。

20058乚 。

20059乛 。

20101亅 。

19969丁 。

.......... 。

从上面的结果,我们可以清楚的看到,一笔的汉字,code是从19968到20101,从小到大排,但到 。

了二笔汉字的第一个字“丁”,CODE为19969,就不按顺序而重新开始了。有了这结果,我们就可以轻 。

松的用SQL语句得到每种笔划汉字归类的第一个或最后一个汉字.

下面用语句得到最后一个汉字:

createtable#t1(idintidentity,codeint,cnwordnvarchar(2)) 。

insert#t1(code,cnword) 。

selectcode,nchar(code)asCNWordfrom#t 。

orderbynchar(code)collateChinese_PRC_Stroke_CS_AS_KS_WS,code 。

selectA.cnword 。

from#t1A 。

leftjoin#t1BonA.id=B.id-1andA.code 。

whereB.codeisnull 。

orderbyA.id 。

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

最后一个汉字:

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

上面可以看出:“亅”是所有一笔汉字排序后的最后一个字,“阝”是所有二笔汉字排序后的最后 。

一个字......等等.

但同时也发现,从第33个汉字“龗(33笔)”后面的笔划有些乱,不正确。但没关系,比“龗”笔划 。

多的只有四个汉字,我们手工加上:齾35笔,齉36笔,靐39笔,龘64笔 。

建汉字笔划表(TAB_HZBH):

createtabletab_hzbh(idintidentity,cnwordnchar(1)) 。

--先插入前33个汉字 。

inserttab_hzbh 。

selecttop33A.cnword 。

from#t1A 。

leftjoin#t1BonA.id=B.id-1andA.code 。

whereB.codeisnull 。

orderbyA.id 。

--再加最后四个汉字 。

setidentity_inserttab_hzbhon 。

go 。

inserttab_hzbh(id,cnword) 。

select35,N'齾' 。

unionallselect36,N'齉' 。

unionallselect39,N'靐' 。

unionallselect64,N'龘' 。

go 。

setidentity_inserttab_hzbhoff 。

go 。

到此为止,我们可以得到结果了,比如我们想得到汉字“国”的笔划:

declare@anchar(1) 。

set@a='国' 。

selecttop1id 。

fromtab_hzbh 。

wherecnword>=@acollateChinese_PRC_Stroke_CS_AS_KS_WS 。

orderbyid 。

id 。

----------- 。

8 。

(结果:汉字“国”笔划数为8) 。

上面所有准备过程,只是为了写下面这个函数,这个函数撇开上面建的所有临时表和固 。

定表,为了通用和代码转移方便,把表tab_hzbh的内容写在语句内,然后计算用户输入一串 。

汉字的总笔划:

createfunctionfun_getbh(@strnvarchar(4000)) 。

returnsint 。

as 。

begin 。

declare@wordnchar(1),@nint 。

set@n=0 。

whilelen(@str)>0 。

begin 。

set@word=left(@str,1) 。

--如果非汉字,笔划当0计 。

set@n=@n+(casewhenunicode(@word)between19968and19968+20901 。

then(selecttop1idfrom( 。

select1asid,N'亅'asword 。

unionallselect2,N'阝' 。

unionallselect3,N'马' 。

unionallselect4,N'风' 。

unionallselect5,N'龙' 。

unionallselect6,N'齐' 。

unionallselect7,N'龟' 。

unionallselect8,N'齿' 。

unionallselect9,N'鸩' 。

unionallselect10,N'龀' 。

unionallselect11,N'龛' 。

unionallselect12,N'龂' 。

unionallselect13,N'龆' 。

unionallselect14,N'龈' 。

unionallselect15,N'龊' 。

unionallselect16,N'龍' 。

unionallselect17,N'龠' 。

unionallselect18,N'龎' 。

unionallselect19,N'龐' 。

unionallselect20,N'龑' 。

unionallselect21,N'龡' 。

unionallselect22,N'龢' 。

unionallselect23,N'龝' 。

unionallselect24,N'齹' 。

unionallselect25,N'龣' 。

unionallselect26,N'龥' 。

unionallselect27,N'齈' 。

unionallselect28,N'龞' 。

unionallselect29,N'麷' 。

unionallselect30,N'鸞' 。

unionallselect31,N'麣' 。

unionallselect32,N'龖' 。

unionallselect33,N'龗' 。

unionallselect35,N'齾' 。

unionallselect36,N'齉' 。

unionallselect39,N'靐' 。

unionallselect64,N'龘' 。

)T 。

whereword>=@wordcollateChinese_PRC_Stroke_CS_AS_KS_WS 。

orderbyidASC)else0end) 。

set@str=right(@str,len(@str)-1) 。

end 。

return@n 。

end 。

--函数调用实例:

selectdbo.fun_getbh('中华人民共和国'),dbo.fun_getbh('中華人民共和國') 。

执行结果:笔划总数分别为39和46,简繁体都行.

当然,你也可以把上面“UNION ALL”内的汉字和笔划改存在固定表内,在汉字 。

列建CLUSTEREDINDEX,列排序规则设定为:

Chinese_PRC_Stroke_CS_AS_KS_WS 。

这样速度更快。如果你用的是BIG5码的操作系统,你得另外生成汉字,方法一样.

但有一点要记住:这些汉字是通过SQL语句Select出来的,不是手工输入的,更不 。

是查字典得来的,因为新华字典毕竟不同于UNICODE字符集,查字典的结果会不正 。

确.

用排序规则的特性得到汉字拼音首字母 。

用得到笔划总数相同的方法,我们也可以写出求汉字拼音首字母的函数。如下:

createfunctionfun_getPY(@strnvarchar(4000)) 。

returnsnvarchar(4000) 。

as 。

begin 。

declare@wordnchar(1),@PYnvarchar(4000) 。

set@PY='' 。

whilelen(@str)>0 。

begin 。

set@word=left(@str,1) 。

--如果非汉字字符,返回原字符 。

set@PY=@PY+(casewhenunicode(@word)between19968and19968+20901 。

then(selecttop1PYfrom( 。

select'A'asPY,N'驁'asword 。

unionallselect'B',N'簿' 。

unionallselect'C',N'錯' 。

unionallselect'D',N'鵽' 。

unionallselect'E',N'樲' 。

unionallselect'F',N'鰒' 。

unionallselect'G',N'腂' 。

unionallselect'H',N'夻' 。

unionallselect'J',N'攈' 。

unionallselect'K',N'穒' 。

unionallselect'L',N'鱳' 。

unionallselect'M',N'旀' 。

unionallselect'N',N'桛' 。

unionallselect'O',N'漚' 。

unionallselect'P',N'曝' 。

unionallselect'Q',N'囕' 。

unionallselect'R',N'鶸' 。

unionallselect'S',N'蜶' 。

unionallselect'T',N'籜' 。

unionallselect'W',N'鶩' 。

unionallselect'X',N'鑂' 。

unionallselect'Y',N'韻' 。

unionallselect'Z',N'咗' 。

)T 。

whereword>=@wordcollateChinese_PRC_CS_AS_KS_WS 。

orderbyPYASC)else@wordend) 。

set@str=right(@str,len(@str)-1) 。

end 。

return@PY 。

end 。

--函数调用实例:

selectdbo.fun_getPY('中华人民共和国'),dbo.fun_getPY('中華人民共和國') 。

结果都为:ZHRMGHG 。

你若有兴趣,也可用相同的方法,扩展为得到汉字全拼的函数,甚至还可以得到全拼的读 。

音声调,不过全拼分类大多了。得到全拼最好是用对照表,两万多汉字搜索速度很快,用对照 。

表还可以充分利用表的索引.

排序规则还有很多其它的巧妙用法。欢迎大家共同探讨.

最后此篇关于整理一下SQLSERVER的排序规则的文章就讲到这里了,如果你想了解更多关于整理一下SQLSERVER的排序规则的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com