SQL SERVER的定序 利用定序特點計算漢字筆劃和取得拼音首字母 )

來源:互聯網
上載者:User
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
-----------------

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.