在涉及归类和数据类型差异的情况下,我对系统的行为感到非常困惑。
作为最小的示例,我将相同的Unicode值输入到两个不同表的单列中。在一个表中,该列是varchar
和的某种排序规则,在另一表中是的nvarchar
和另一种排序规则。代码和结果:
create table cn(code nvarchar(max) collate Latin1_General_CI_AS)
create table cv(code varchar(max) collate SQL_Latin1_General_CP1253_CI_AI)
insert cn select N'3VT18021δ'
insert cv select N'3VT18021δ'
select * from cn
select * from cv
--1.
select * from cn inner join cv on cn.code=cv.code
-- Cannot resolve the collation conflict between "SQL_Latin1_General_CP1253_CI_AI" and "Latin1_General_CI_AS" in the equal to operation.
--2.
select * from cn inner join cv on cn.code=cv.code collate SQL_Latin1_General_CP1253_CI_AI
-- returns one row
--3.
select * from cn inner join cv on cn.code =cv.code collate Latin1_General_CI_AS
-- returns 0 rows
--4.
select * from cn inner join cv on cn.code collate SQL_Latin1_General_CP1253_CI_AI =cv.code
-- returns one row
--5.
select * from cn inner join cv on cn.code collate Latin1_General_CI_AS =cv.code
-- returns one row
我的笔记:
情况1:我理解排序规则有所不同
情况2和5 :(正确)返回一行。为什么将字段归类为其自己的归类有好处?
案例3和4:为什么一次将一个排序规则转换为另一种排序规则,而不是另一种转换呢?
当然,所有这些由于数据类型的差异而变得更加复杂。
情况2和5 :(正确)返回一行。为什么将字段归类为其自己的归类有好处?
当你明确地使用COLLATE
一个子句中的值两者表达的侧面明确地转换为整理,因此不存在冲突。
案例3和4:为什么一次将一个排序规则转换为另一种排序规则,而不是另一种转换呢?
您的一列是varchar
,因此将其从一种排序规则更改为另一种排序规则时,其值也会更改。特别是当您COLLATE
将表中的值cv
归为collation时Latin1_General_CI_AS
。至于'δ'
是不是在整理的可用角色varchar
,变成一个'd'
和'3VT18021d'
做不相等N'3VT18021δ'
。您可以在下面看到它:
SELECT code COLLATE Latin1_General_CI_AS
FROM cv;
您需要将值显式转换为nvarchar
first:
select *
from cn
inner join cv on cn.code = CONVERT(nvarchar(MAX),cv.code) collate Latin1_General_CI_AS;
--Returns one row now
编辑:要解释为什么查询3并没有返回数据,查询5呢,这是因为定位的COLLATE
S和时隐式转换会发生。
cn.code =cv.code collate Latin1_General_CI_AS --3
cn.code collate Latin1_General_CI_AS =cv.code --5
对于查询3,COLLATE
表达式为on cv.code
,即varchar
。结果,该值的排序规则首先更改,并且字符'δ'
丢失。然后nvarchar
,由于数据类型优先级,它隐式转换为。
但是,对于查询5,COLLATE
上的cn.code
是nvarchar
。结果,当更改值的排序规则时,不会丢失任何字符。由于cv.code
没有显式的COLLATE
,因此首先将其转换为nvarchar
(由于数据类型优先),然后再进行整理;不会丢失任何字符。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句