SQL Server 排序规则(摘)
3Sql 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
解決這個問題語句可以這樣寫:
select?*?from?#t1?A?inner?join?#t2?B?on?A.name=B.name?collate?Chinese_PRC_CI_AI_WS??
二、排序規則簡介:
MS是這樣描述的:“在Microsoft SQL Server 2000中,字符串的物理存儲由排序規則控制。排序規則指定表示每個字符的位模式以及存儲和比較字符所使用的規則?!?br />在查詢分析器內執行下面語句,可以得到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區分
區分大小寫:是否想讓比較將大寫字母和小寫字母視為不等
區分重音:是否想讓比較將重音和非重音字母視為不等
區分假名:是否想讓比較將片假名和平假名日語音節視為不等
區分寬度:是否想讓比較將半角字符和全角字符視為不等
三、排序規則的應用:
例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???
droptable?#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?????????? 三
*/
四、在實踐中排序規則應用的擴展
例1:用排序規則的特性計算漢字筆劃
要計算漢字筆劃,Windows多國漢字,Unicode目前收錄漢字共20902個。簡體GBK碼漢字Unicode值從19968開始。
首先,我們先用SqlServer方法得到所有漢字,用Sql語句就可以得到:
select?top?20902?code=identity(int,19968,1)?into?#t?from?syscolumns?a,syscolumns?b
select?code,nchar(code)?as?CNWord?from?#t
select?code,nchar(code)?as?CNWord?from?#t?order?by?nchar(code)?collate?Chinese_PRC_Stroke_CS_AS_KS_WS,code
從上面的結果可以看出,一筆的漢字,code是從19968到20101,從小到大排,但到了二筆漢字的第一個字“丁”,code為19969,就不按順序而重新開始了。有了這個結果,就可以輕松用Sql語句得到每種筆劃漢字歸類的第一個或最后一個漢字。
下面用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筆)”后面的筆劃有些亂,不正確??梢杂檬止ぜ由媳取?/span>龗”筆劃多的漢字:齾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?A.code<B.code?where?B.code?is?null?order?by?A.id
--再加最后四個漢字
set?identity_insert?tab_hzbh?on
insert?tab_hzbh(id,cnword)?select?35,N'齾'?union?all?select?36,N'齉'?union?all?select?39,N'靐'?union?all?select?64,N'龘'
set?identity_insert?tab_hzbh?off 到此為止,我們就可以得到結果了。比如我們想得到漢字“國”的筆劃:
declare?@a?nchar(1)
set?@a='國'
select?top?1?id?from??tab_hzbh?where?cnword>=@a?collate?Chinese_PRC_Stroke_CS_AS_KS_WS?order?by?id
(結果:漢字“國”筆劃數為8)
有了上面的準備,可以寫這樣一個函數,用來計算字符串中漢字的筆劃數:
create?function?fun_getbh(@str?nvarchar(4000))
returns?int
as
begin
????declare?@word?nchar(1),@n?int
????set?@n=0
????while?len(@str)>0
????begin
????????set?@word=left(@str,1)
????????--如果非漢字,筆劃當0計
????????set?@n=@n+(case?when?unicode(@word)?between?19968?and?19968+20901
????????then?(select?top?1?id?from?(
????????select?1?as?id,N'亅'?as?word?
????????union?all?select?2,N'阝'?
????????union?all?select?3,N'馬'?
????????union?all?select?4,N'風'?
????????union?all?select?5,N'龍'?
????????union?all?select?6,N'齊'?
????????union?all?select?7,N'龜'?
????????union?all?select?8,N'齒'?
????????union?all?select?9,N'鴆'?
????????union?all?select?10,N'齔'?
????????union?all?select?11,N'龕'?
????????union?all?select?12,N'龂'?
????????union?all?select?13,N'齠'?
????????union?all?select?14,N'齦'?
????????union?all?select?15,N'齪'?
????????union?all?select?16,N'龍'?
????????union?all?select?17,N'龠'?
????????union?all?select?18,N'龎'?
????????union?all?select?19,N'龐'?
????????union?all?select?20,N'龑'?
????????union?all?select?21,N'龡'?
????????union?all?select?22,N'龢'?
????????union?all?select?23,N'龝'?
????????union?all?select?24,N'齹'?
????????union?all?select?25,N'龣'?
????????union?all?select?26,N'龥'?
????????union?all?select?27,N'齈'?
????????union?all?select?28,N'龞'?
????????union?all?select?29,N'麷'?
????????union?all?select?30,N'鸞'?
????????union?all?select?31,N'麣'?
????????union?all?select?32,N'龖'?
????????union?all?select?33,N'龗'?
????????union?all?select?35,N'齾'?
????????union?all?select?36,N'齉'?
????????union?all?select?39,N'靐'?
????????union?all?select?64,N'龘'?
????????)?T?
????????where?word>=@word?collate?Chinese_PRC_Stroke_CS_AS_KS_WS
????????order?by?id?ASC)?else?0?end)
????????set?@str=right(@str,len(@str)-1)
????end
????return?@n
end
函數調用實例:
select?dbo.fun_getbh('中華人民共和國'),dbo.fun_getbh('中華人民共和國')執行結果:筆劃總數分別為36和46。
例2:用排序規則得到漢字拼音首字母
create?function?fun_getPY(@str?nvarchar(4000))
returns?nvarchar(4000)
as
begin
????declare?@word?nchar(1),@PY?nvarchar(4000)
????set?@PY=''
????while?len(@str)>0
????begin
????????set?@word=left(@str,1)
????????--如果非漢字字符,返回原字符
????????set?@PY=@PY+(case?when?unicode(@word)?between?19968?and?19968+20901
????????then?(select?top?1?PY?from?(
????????select?'A'?as?PY,N'驁'?as?word
????????union?all?select?'B',N'簿'
????????union?all?select?'C',N'錯'
????????union?all?select?'D',N'鵽'
????????union?all?select?'E',N'樲'
????????union?all?select?'F',N'鰒'
????????union?all?select?'G',N'腂'
????????union?all?select?'H',N'夻'
????????union?all?select?'J',N'攈'
????????union?all?select?'K',N'穒'
????????union?all?select?'L',N'鱳'
????????union?all?select?'M',N'旀'
????????union?all?select?'N',N'桛'
????????union?all?select?'O',N'漚'
????????union?all?select?'P',N'曝'
????????union?all?select?'Q',N'囕'
????????union?all?select?'R',N'鶸'
????????union?all?select?'S',N'蜶'
????????union?all?select?'T',N'籜'
????????union?all?select?'W',N'鶩'
????????union?all?select?'X',N'鑂'
????????union?all?select?'Y',N'韻'
????????union?all?select?'Z',N'咗'
????????)?T?
????????where?word>=@word?collate?Chinese_PRC_CS_AS_KS_WS?
????????order?by?PY?ASC)?else?@word?end)
????????set?@str=right(@str,len(@str)-1)
????end
????return?@PY
end
函數調用實例:
select?dbo.fun_getPY('中華人民共和國'),dbo.fun_getPY('中華人民共和國')
執行結果:ZHRMGHG
例3:獲取漢字字符串的拼音首字母
if?exists?(select?*?from?dbo.sysobjects?where?id?=?object_id(N'[dbo].[fGetPy]')?and?xtype?in?(N'FN',?N'IF',?N'TF'))
????drop?function?[dbo].[fGetPy]
GO
--創建取拼音函數
create?function?fGetPy(@Str?varchar(500)='')
returns?varchar(500)
as
begin
?declare?@strlen?int,@return?varchar(500),@ii?int
?declare?@n?int,@c?char(1),@chn?nchar(1)
?select?@strlen=len(@str),@return='',@ii=0
?set?@ii=0
?while?@ii<@strlen
?begin
??select?@ii=@ii+1,@n=63,@chn=substring(@str,@ii,1)
??if?@chn>'z'
??select?@n?=?@n?+1
?????,@c?=?case?chn?when?@chn?then?char(@n)?else?@c?end
???from(
????select?top?27?*?from?(
?????select?chn?=?'吖'
?????union?all?select?'八'
?????union?all?select?'嚓'
?????union?all?select?'咑'
?????union?all?select?'妸'
?????union?all?select?'發'
?????union?all?select?'旮'
?????union?all?select?'鉿'
?????union?all?select?'丌'??--because?have?no?'i'
?????union?all?select?'丌'
?????union?all?select?'咔'
?????union?all?select?'垃'
?????union?all?select?'嘸'
?????union?all?select?'拏'
?????union?all?select?'噢'
?????union?all?select?'妑'
?????union?all?select?'七'
?????union?all?select?'呥'
?????union?all?select?'仨'
?????union?all?select?'他'
?????union?all?select?'屲'??--no?'u'
?????union?all?select?'屲'??--no?'v'
?????union?all?select?'屲'
?????union?all?select?'夕'
?????union?all?select?'丫'
?????union?all?select?'帀'
?????union?all?select?@chn)?as?a
????order?by?chn?COLLATE?Chinese_PRC_CI_AS?
???)?as?b
??else?set?@c='a'
??set?@return=@return+@c
?end
?return(@return)
end
go
--測試
select?dbo.fgetpy('東莞市')?as?東莞市,dbo.fgetpy('ab中c國人')?as?中國人
--刪除拼音函數
drop?function?fgetpy?
-------------------------------------------------------------------------------------------------------------------------------------------
摘自:http://www.cnblogs.com/hzuIT/articles/947411.html
總結
以上是生活随笔為你收集整理的SQL Server 排序规则(摘)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux设置自动关机命令,Linux怎
- 下一篇: TableView详解