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.codewhere 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
TeamViewer 連線後無法操作的解決方法
teamviewer遠端控制計算機 圖1 登入進入遠端控制 2.在連線了之後一些使用者無法對遠端的非電腦進行操作,大家可以自己在下圖所示的紅色區域中進行嘗試,只能連線,但不能控制。無法操作示例 圖2 嘗試控制桌面 3.接著使用滑鼠單擊teamviewer控制介面上方的動作選項卡,開啟之後接著將右側側...
Oracle 某條記錄無法進行操作,排坑
oracle 某條記錄無法進行操作,排坑 oracle表中的,某條記錄無法進行刪除,更新,等操作。試了各種方法,無論時在idea工具裡操作,還是使用sql developer裡面,sql語句,都試過了,都不行,於是準備刪除該錶,結果提示 61000 54 ora 00054 資源正忙,但指定以 no...
解決centos使用者組更改操作,無法生效的問題。
劇情是這樣的,筆者在使用docker的remote api時,使用php,訪問檔案docker.sock,一直報許可權錯誤。查了一下許可權 ll var run docker.sockll var run docker.sock srw rw 1 root docker 0 oct 15 17 29...