Unicode字符导致SQL Server 2005中的字符串比较问题
-
21-09-2019 - |
题
此查询:
select *
from op.tag
where tag = 'fussball'
,则返回具有“fußball”的标记列的值的结果。列 “标记” 被定义为为nvarchar(150)。
虽然我知道他们是类似的话语法,任何人都可以解释和捍卫这种行为?我认为这是关系到相同的排序规则设置,让你可以改变一个列/表区分大小写,但谁希望这种行为?在列的唯一约束还使上一个值的刀片故障时其他存在由于违反约束。如何关闭这个功能?
后续的奖金点问题。解释为什么此查询不返回任何行:
select 1
where 'fußball' = 'fussball'
奖金问题(答):@ScottCher向我指出私下认为,这是由于字符串“fussball”被视为一个varchar。此查询DOES返回结果:
select 1
where 'fußball' = cast('fussball' as nvarchar)
但随后再次,这一个不:
select 1
where cast('fußball' as varchar) = cast('fussball' as varchar)
我感到困惑。
解决方案
我想Unicode排序规则集为连接/表/数据库指定SS ==ß。后者的行为是因为它是一个错误的快速路径上,也可能是做一个二进制比较,也许你不是在SS传递正确的编码(我同意这是愚蠢的)。
http://unicode.org/reports/tr10/#Searching 提到U + 00DF是特例,。下面是一个有见地的摘录:
语言敏感搜索和 匹配密切相关 排序规则。这比较成字符串 在一些实力水平相等的是那些 应该做的,当匹配 语言敏感的匹配。对于 例如,在主强度,“SS” 将对阵“SS”根据 在UCA和“AA”将匹配“A”的 的UCA的丹麦剪裁。
其他提示
在SELECT 确实返回一行使用归类Latin1_General_CI_AS(SQL2000)。
它确实不的使用归类Latin1_General_BIN。
可以通过使用COLLATE <归类>分配一个表列的对照N / VARCHAR后关键字。
您还可以使用特定归类使用语法比较字符串
string1 = string2 COLLATE < collation >
一些辅助的答案 - 不是完整的一个你的问题,但仍可能有帮助的:
如果你尝试:
SELECT 1 WHERE N'fußball' = N'fussball'
你会得到“1” - 用“N”来表示Unicode时,这两个字符串被认为是相同的 - 为什么是这样的话,我不知道(但)
要找到的默认排序作为一个服务器,可使用
SELECT SERVERPROPERTY('Collation')
要找到数据库中的一个给定的列强>的的整理,使用以下查询:
SELECT
name 'Column Name',
OBJECT_NAME(object_id) 'Table Name',
collation_name
FROM sys.columns
WHERE object_ID = object_ID('your-table-name')
AND name = 'your-column-name'
奖金问题(回答):@ScottCher 向我指出私下认为,这 是由于字符串字面 “fussball”被视为一个varchar。 此查询DOES返回结果:
select 1 where 'fußball' =
cast('fussball' as nvarchar)
在这里你处理SQL Server数据类型优先规则,在的数据类型优先级。比较所使用的更高的优先级类型完成始终:
当操作者将两个 不同数据类型的表达, 对于数据类型的优先级的规则 指定该数据与所述输入 低优先级被转换成 数据类型具有较高的优先级。
由于nvarchar的具有比VARCHAR一个更高的优先级,在你的例子的比较将发生起诉nvarchar类型,所以它是真正完全一样select 1 where N'fußball' =N'fussball'
(即使用Unicode类型)。我希望这也让人们清楚为什么你最后的情况下,不返回任何行。