"無法解決等於運算的排序規則沖突."
壹、誤差分析:
此錯誤是由不壹致的排序規則導致的。讓我們做壹個測試,比如:
創建表#t1(
name varchar(20) collate阿爾巴尼亞語_CI_AI_WS,
值int)
創建表#t2(
name varchar(20)整理中文,
值int)
構建表後,執行連接查詢:
select * from # t 1 A . name = B . name上的內部聯接#t2 B
這樣,錯誤出現了:
服務器:消息446,級別16,狀態9,行1。
無法解決等於操作的排序規則沖突。
消除此錯誤的最簡單方法是在連接表時指定其排序規則,這樣錯誤就不會再次出現。聲明內容如下:
選擇*
從#t1 A內部聯接#t2 B
整理中文
二。歸類介紹:
什麽是排序規則?MS這樣描述:“在Microsoft SQL Server 2000中,字符串的物理存儲是由排序規則控制的。歸類規則指定表示每個字符的位模式以及用於存儲和比較字符的規則。
在查詢分析器中執行以下語句,以獲取SQL SERVER支持的所有排序規則。
select * from ::fn_helpcollations()
歸類名稱由兩部分組成。第壹部分指的是該排序規則支持的字符集。
比如:
中文_PRC_CS_AI_WS
前半部分:指UNICODE字符集,Chinese_PRC_ pointer的排序規則指向大陸簡體中文字符UNICODE。
排序規則的後半部分是後綴的意思:
_BIN二元排序
_CI(CS)區分大小寫,CI不區分大小寫,CS區分大小寫。
_AI(AS)是否區分重音,AI不區分,AS也是。
_KI(KS)是否區分假名類型,KI不區分,KS區分。
_WI(WS)是否區分寬度WI不區分,WS區分。
區分大小寫:如果希望比較將大寫字母和小寫字母視為不相等,請選擇此選項。
區分重音:如果希望比較將重音和非重音視為不相等,請選擇此選項。如果選擇了此選項,比較還會將重音不同的字母視為不相等。
區分假名:如果您希望比較將片假名和平假名的日語音節視為不相等,請選擇此選項。
區分寬度:如果希望比較將半角字符和全角字符視為不相等,請選擇此選項。
三。排序規則的應用:
SQLSERVER提供了大量特定於WINDOWS和SQL SERVER的排序規則,但其應用往往被開發人員忽略。其實在實踐中是很有用的。
例1:讓表格的姓名列的內容按拼音排序;
創建表#t(id int,name varchar(20))
Insert #t select 1,'中'
工會全選2,“國家”
工會全選3,'人'
Union all select 4,' A '
select * from # t order by name collate中文_PRC_CS_AS_KS_WS
刪除表#t
/*結果:
id名稱
- -
4 a
2個國家
三個人
在1
*/
示例2:讓表的名稱列的內容按姓氏筆畫排序:
創建表#t(id int,name varchar(20))
插入#t選擇1,'三'
聯合全選2,' b '
工會全選3,'二'
工會全選4,'壹'
工會全選5,'十'
select * from # t order by name collate中文_PRC_Stroke_CS_AS_KS_WS
刪除表#t
/*結果:
id名稱
- -
4易
2 b
3兩個
50十分
1 San
*/
四。校勘在實踐中應用的擴展
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值排序:
從#t中選擇code,nchar(code)作為CNWord
然後,我們用SELECT語句按筆畫排序。
選擇代碼,nchar(代碼)作為CNWord
從#t
按nchar排序(代碼)校對中文_PRC_Stroke_CS_AS_KS_WS,代碼
結果:
代碼CNWord
- -
19968 I
2008
20022 sa
20031
20032嘿
20033
20057 b
20058丫
20059
20101
19969丁
..........
從上面的結果我們可以清楚的看到,漢字壹筆的代碼是從19968到20101,從小到大,但是當漢字兩筆的第壹個字是“丁”,代碼是19969時,又開始亂序。有了這個結果,我們就可以很容易地用SQL語句得到每個筆畫漢字分類的第壹個或最後壹個漢字。
用下面的句子得到最後壹個漢字:
創建表#t1(id int identity,code int,cnword nvarchar(2))
插入#t1(代碼,cnword)
從#t中選擇code,nchar(code)作為CNWord
按nchar排序(代碼)校對中文_PRC_Stroke_CS_AS_KS_WS,代碼
選擇壹個單詞
來自#t1 A
在A.id=B.id-1和A.code & ltb .代碼
其中B.code為空
按編號排序
得到36個漢字,每個漢字按照每個筆畫數的中文_PRC_Stroke_CS_AS_KS_WS排序規則進行排序。
最後壹個漢字:
龍,祁桂牙,小生,膠,龍,池塘,池塘,池塘,池塘,池塘,池塘,池塘,池塘。
從上面可以看出,“莫”是所有漢字排序後的最後壹個字,“裏”是所有兩個漢字排序後的最後壹個字...諸如此類。
但同時也發現第33個漢字“諸(33筆)”後的筆畫有些亂,不正確。不過沒關系。只比“諸”筆畫多了四個漢字。我們手動添加:35劃、36劃、39劃、64劃。
建立漢字筆畫表(TAB _ HZBH);
創建表tab_hzbh(id int identity,cnword nchar(1))
-首先插入前33個漢字
插入制表符_hzbh
選擇前33個單詞
來自#t1 A
在A.id=B.id-1和A.code & ltb .代碼
其中B.code為空
按編號排序
-添加最後四個漢字。
set identity_insert tab_hzbh on
去
insert tab_hzbh(id,cnword)
選擇35,N '
聯合全選36,N '
聯合所有選擇39,北?'
Union all select 64,N '
去
設置identity_insert tab_hzbh關閉
去
到目前為止,我們可以得到這樣的結果,例如,我們想得到漢字“國”的筆畫:
聲明@a nchar(1)
Set @a=' country '
選擇前1 id
來自tab_hzbh
其中cnword & gt=@a collate中文_PRC_Stroke_CS_AS_KS_WS
按id排序
身份證明(identification)
-
八
(結果:漢字“國”的筆畫數為8)
上面所有的準備過程就是為了寫下面這個函數,把上面建立的所有臨時表和固定表放在壹邊,為了方便通用性和代碼轉移,把table tab_hzbh的內容寫在語句中,然後計算用戶輸入的壹串漢字的總筆畫數:
創建函數fun_getbh(@str nvarchar(4000))
返回整數
如同
開始
聲明@word nchar(1),@n int
set @n=0
while len(@str)>0
開始
set @word=left(@str,1)
-如果不是漢字,筆畫會計為0。
設置@n=@n+(當unicode(@word)介於19968和19968+20901之間時的大小寫
然後(選擇top 1 id from(
選擇1作為id,N '個作為詞。
' Union all select 2,N '
聯合所有選擇3,N '馬'
Union all select 4,N' wind '
聯盟所有選擇5,N '龍'
聯合所有選擇6,N' qi '
工會全選7,N '海龜'
聯合所有選擇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 '牙齦'
工會全選15,N '急'
工會全選16,N '龍'
Union all select 17,N '
聯合所有選擇18,無'
Union all select 19,N' pang '
' Union all select 20,N '
Union all select 21,N '
Union all select 22,N '
聯合全選23,N '
' Union all select 24,N '
' Union all select 25,N '
聯合全選26,N '
聯合全選27,N '
聯合全選28,N '
聯合全選29,N '
工會全選30,N '欒'
Union all select 31,N' Kun '
Union all select 32,N '
Union all select 33,N '
Union all select 35,N '
聯合全選36,N '
聯合所有選擇39,北?'
Union all select 64,N '
)T
其中word & gt=@word collate中文_PRC_Stroke_CS_AS_KS_WS
按id排序ASC)否則0結束)
set @str=right(@str,len(@str)-1)
結束
return @n
結束
-函數調用實例:
選擇dbo.fun_getbh('中華人民共和國'),dbo.fun_getbh('中華人民共和國')。
執行結果:總筆畫數分別為39和46,簡繁體筆畫均可。
當然,也可以將上面“並集全部”中的漢字和筆畫改為固定表,在漢字列中建立聚簇索引,列排序規則設置為:
中文_ PRC _筆畫_CS_AS_KS_WS
這樣更快。如果妳用BIG5代碼的操作系統,妳也要用同樣的方法生成漢字。但是有壹點要記住:這些漢字是SQL語句選擇的,不是手工輸入的,也不是查字典得到的,因為新華字典畢竟不同於UNICODE字符集,查字典的結果會不正確。
利用排序規則的特征獲取漢語拼音首字母
用同樣的方法得到總筆畫數,我們也可以寫壹個函數求出漢語拼音的第壹個字母。如下所示:
創建函數fun_getPY(@str nvarchar(4000))
返回nvarchar(4000)
如同
開始
聲明@word nchar(1),@PY nvarchar(4000)
set @PY= ' '
while len(@str)>0
開始
set @word=left(@str,1)
-如果不是漢字,返回原字。
設置@PY=@PY+(當unicode(@word)介於19968和19968+20901之間時的大小寫
然後(選擇top 1 PY from(
選擇' A '作為PY,N' ao '作為word
Union all select 'B ',N' book '
聯合所有選擇“C”,N“錯誤”
聯合所有選擇' D ',N '年'
聯合所有選擇' E ',N' pin '
Union all select 'F ',N' Kun '
Union all select 'G ',N '
Union all select 'H ',N ' a '
Union all select 'J ',N ' '。
Union all select 'K ',N '
Union all select 'L ',N' gue '
Union all select 'M ',N '
聯合所有選擇' N ',N' bang '
Union all select 'O ',N' Lu '
聯合所有選擇“P”,N“曝光”
工會都選擇'問',N '歡'
Union all select 'R ',N '
聯合所有選擇,N
Union all select 'T ',N '
Union all select 'W ',N' u '
Union all select 'X ',N '
Union all select 'Y ',N ' rhyme
聯合所有選擇“Z”,N“bang”
)T
其中word & gt=@word collate中文_PRC_CS_AS_KS_WS
order by PY ASC) else @word end)
set @str=right(@str,len(@str)-1)
結束
返回@PY
結束
-函數調用實例:
選擇dbo.fun_getPY('中華人民共和國'),dbo.fun_getPY('中華人民共和國')。
結果都是:ZHRMGHG
如果妳有興趣,也可以用同樣的方法擴展成獲取漢字全拼的功能,甚至可以獲取全拼的讀音和聲調,但是全拼的分類居多。最好使用對照表來獲得整個拼寫。兩萬多個漢字的搜索速度很快,使用對照表可以充分利用表的索引。