天天看點

表union時出現的排序規則問題

union表時出現Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CS_AS" and "SQL_Latin1_General_CP850_BIN2" in the UNION operation.此為兩張表字段排序規則不同引起。

用sp_help  'tablename'   查出字段的collate值發現不一樣後

ALTER TABLE tablename

   ALTER COLUMN  columnname  nvarchar(10) COLLATE SQL_Latin1_General_CP850_BIN2

更改字段排序規則後即可union

或在字段後加排序規則也可 如:

(select NodeID COLLATE SQL_Latin1_General_CP1_CS_AS,NodeDescription COLLATE SQL_Latin1_General_CP1_CS_AS,ParentNode COLLATE SQL_Latin1_General_CP1_CS_AS,NodeLink COLLATE SQL_Latin1_General_CP1_CS_AS,NodeTarget COLLATE SQL_Latin1_General_CP1_CS_AS FROM MENU)

union

(select FuncID COLLATE SQL_Latin1_General_CP1_CS_AS,FuncName COLLATE SQL_Latin1_General_CP1_CS_AS,ParentID COLLATE SQL_Latin1_General_CP1_CS_AS,URL COLLATE SQL_Latin1_General_CP1_CS_AS,Target COLLATE SQL_Latin1_General_CP1_CS_AS FROM SystFunctions)

但此舉非常麻煩

關于排序規則參考如下轉載:

巧用排序規則計算漢字筆畫

  排序規則簡介

  對于排序規則,微軟在相關檔案中是這樣描述的:在 MS SQL Server 2000中,字元串的實體存儲由排序規則控制,排序規則指定表示每個字元的位模式以及存儲和比較字元所使用的規則。

  在“查詢分析器”内執行下面的語句,可以得到SQL Server支援的所有排序規則。

  select * from ::fn_helpcollations()

  排序規則名稱由兩部分構成,如Chi nese_PRC_CS_AI_WS,前半部分是指本排序規則所支援的字元集,Chinese_PRC指針對大陸簡體字UNICODE的排序規則。後半部分也叫字尾,常見的字尾及含義如下:

  _BIN 二進制排序

  _CI(CS)是否區分大小寫,CI不區分,CS區分

  _AI(AS)是否區分重音,AI不區分,AS區分

  _WI(WS)是否區分寬度(半角字元/全角字元),WI不區分,WS區分

  _KI(KS)是否區分假名類型,KI不區分,KS區分

  排序規則的應用

  SQL Server提供了大量的Windows和SQL Server專用的排序規則,但它的應用往往被開發人員忽略。其實它在實踐中大有用處。比如下面的例子:讓表中NAME列的内容按姓氏筆畫排序,代碼如下,結果如圖1所示。

  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 col late Chi nese_PRC_Stroke_CS_AS_KS_WS

  drop table #t

  應用擴充

  應用SQL Server漢字排序規則我們不僅可以按拼音、筆畫等排序,還可以利用這種功能來處理漢字的一些難題,比如計算漢字筆畫。

  1.得到全部漢字并按筆畫排序

  我們知道,Windows的UNICODE目前收錄漢字共20902個,簡體GBK碼漢字U NICODE值從19968開始。首先,我們用SQL Server的方法得到所有的漢字。注意,不是用字典,而是利用SQL語句得到按U NICODE值排序的漢字,結果如圖2所示。

  select top 20902 code=identity(int,19968,1) into #t from syscolumns a,syscolumns b

  select code,nchar(code) as CNWord from #t

  然後,我們用下面的語句讓它們按筆畫排序,結果如圖3所示。

  select code,nchar(code) as CNWord from #t order by nchar(code) collate Chinese_ PRC_Stroke_ CS_AS_KS_WS,code

  2.得到标志性漢字

  從上面的結果中,我們可以看到:一筆的漢字,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

  where B.code is null

  order by A.id

  在得到的36個漢字中,每個漢字都是每種筆畫數按Chinese_PRC_Stroke_CS_AS _KS_WS規則排序的最後一個漢字,它們是:亅阝馬風龍齊龜齒鸩龀龛龂龆龈龊龍龠龎龐龑龡龢龝齹龣龥齈龞麷鸞麣龖龗齾齉龘。

  同時,我們發現,從第33個漢字“龗(33筆)”後面的筆畫有些亂,不正确。但沒關系,比“龗”筆畫多的隻有四個漢字,我們手工添加即可:齾35筆,齉36筆,靐39筆,龘64筆

  3.建漢字筆畫表

  建漢字筆畫表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

  where B.code is null

  order by A.id

  --再加最後四個漢字

  set identity_insert tab_hzbh on

  go

  insert tab_hzbh(id,cnword)

  select 35,N'齾'

  union all select 36,N'齉'

  union all select 39,N'靐'

  union all select 64,N'龘'

  go

  set identity_insert tab_hzbh off

  go

  4.計算漢字筆畫

  到此為止,我們可以得到結果了,比如我們想得到漢字“國”的筆畫,可以用下面的代碼:

  declare @a nchar(1)

  set @a='國'

  select top 1 id

  from tab_hzbh

  where cnword>[email protected] collate Chinese_PRC_ Stroke_CS_AS_KS_WS

  order by id

  結果為8,正确。

  5.使用自定義函數

  上面的所有過程完全可以用一個函數代替,為了增加通用性,我們把表TAB_HZBH的内容寫在語句内。

  下面的函數可以幫助我們計算使用者輸入的漢字字元串的總筆畫。

  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 @[email protected]+(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>[email protected] 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

  函數調用執行個體如下,計算結果分别為39和46。

  select dbo.fun_getbh('中華人民共和國'),dbo.fun_getbh('中華人民共和國')

  當然,你也可以把上面“UNION ALL”内的漢字和筆畫改存在固定表内,在漢字列建CLUSTERED INDEX,列排序規則設定為:Chinese_PRC_Stroke_CS_AS_ KS_WS,這樣速度更快。

  提示:如果你用的是BIG5碼的作業系統,就得另外生成漢字,方法同上。但有一點要記住:這些漢字是通過SQL語句SELECT出來的,不是手工輸入的,更不是查字典得來的,因為新華字典不同于UNI CODE字元集,使用字典的結果反而不正确。

  一個常見問題的解決

  在應用SQL Server資料庫做跨庫多表連接配接查詢時,若兩資料庫預設字元集不同,系統就會出現這樣的提示:“無法解決equal to操作的排序規則沖突。” 為了給朋友們一個更直覺的認識,我們“模拟”一下這個錯誤。

  1.先建立兩個排序規則不同的表

  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 )

  2.表建好後,執行連接配接查詢

  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