在SQL Server 2016中为列设置排序规则
问题描述:
我正在对排序规则的代码进行测试。在SQL Server 2016中为列设置排序规则
declare @table table
(
col1 varchar(10) collate Latin1_General_CS_AS
-- modified for column
)
insert into @table
values('abcd')
declare @table1 table
(
col2 varchar(10)
--database default(collate SQL_Latin1_General_CP1_CI_AS)
)
insert into @table1
values('abcd')
-- executing this results in an error 'Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CS_AS" in the equal to operation.'
select *
from @table a
join @table1 b on a.col1 = b.col2
--executing below works fine
select *
from @table a
join @table1 b on a.col1 collate Latin1_General_CS_AS = b.col2
--executing below again throws error
select *
from @table a
join @table1 b on a.col1 collate Latin1_General_CS_AS = b.col2 collate SQL_Latin1_General_CP1_CI_AS
需要理解,虽然我在表变量中指定排序规则,但仍然会导致错误。
我在做什么错?
答
您只在比较的一侧指定collate
(哪一边无关紧要)。
--executing below works fine
select * from @table a join @table1 b
on a.col1 collate Latin1_General_CS_AS = b.col2
--executing below also works fine
select * from @table a join @table1 b
on a.col1 = b.col2 collate SQL_Latin1_General_CP1_CI_AS
不能指定的比较是在同一时间两个不同的排序规则,正如你在最后的例子有(...... CS_AS & ...... CI_AS)。
答
基本原则是您必须对列进行整理以便比较正常工作。
如果a.col1归类Latin1_General_CS_AS
然后 你可以用它们
的一个上a.col1 = b.col2整理Latin1_General_CS_AS
上a.col1整理Latin1_General_CS_AS = B。 COL2
a.col1整理SQL_Latin1_General_CP1_CI_AI = b.col2整理 SQL_Latin1_General_CP1_CI_AI(你可以,只要它是改变两侧相同)
因此,即使在创建表时指定它不会工作,我们仍然需要在where子句中提及吗? – omkar
@omkar当两个列的排序规则不同时,您必须选择一个排序规则以用于比较的两侧。 - 在表级别指定排序规则可让您设置默认排序规则,以便与字符串文字进行比较。 http://rextester.com/ZPF30783 – SqlZim
@omkar你只需要在join子句的两边使用不同的排序规则时指定它。在你的情况下,'a'和'b'使用不同的排序规则,所以你必须指定使用哪一个。 –