天天看点

表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