Sql server 导致SQL Server 2005字符串比较中出现问题的Unicode字符
此查询:Sql server 导致SQL Server 2005字符串比较中出现问题的Unicode字符,sql-server,unicode,collation,string-comparison,Sql Server,Unicode,Collation,String Comparison,此查询: select * from op.tag where tag = 'fussball' 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' 返回标记列值为“fußball”的
select *
from op.tag
where tag = 'fussball'
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'
返回标记列值为“fußball”的结果。列“标签”定义为nvarchar(150)
虽然我理解他们是这样的,但有人能解释和捍卫这种行为吗?我假设它与允许您更改列/表的大小写敏感度的相同排序规则设置有关,但是谁会想要这种行为呢?列上的唯一约束也会导致一个值的插入失败,而另一个值由于约束冲突而存在。我怎么关掉这个
跟进奖金积分问题。解释此查询不返回任何行的原因:
select 1
where 'fußball' = 'fussball'
额外问题(答案?)@ScottCher私下向我指出,这是因为字符串文字“fussball”被视为varchar。此查询不返回结果:
select 1
where 'fußball' = cast('fussball' as nvarchar)
但同样,这一条并没有:
select 1
where cast('fußball' as varchar) = cast('fussball' as varchar)
我很困惑。我猜您的连接/表/数据库的Unicode排序规则集指定ss==ß。后一种行为可能是因为它在错误的快速路径上,或者可能它进行了二进制比较,或者可能您没有以正确的编码传递ß(我同意这是愚蠢的) 提到U+00DF是特殊情况。以下是一段深刻的摘录: 对语言敏感的搜索和分析 匹配与否密切相关 整理。比较为 在某些强度水平上相等的是 这样做时应该匹配 语言敏感匹配。对于 例如,一次强度为“ß” 将根据 UCA和“aa”将与a中的“å”匹配 UCA的丹麦剪裁 SELECT确实返回一行,其排序规则为Latin1\u General\u CI\u AS(SQL2000) 它与Latin1\u General\u BIN的排序规则不一致 可以在N/VARCHAR之后使用COLLATE
string1 = string2 COLLATE < collation >
string1=string2排序
一些帮助者的答案-不是您问题的完整答案,但可能仍然有用:
如果您尝试:
SELECT 1 WHERE N'fußball' = N'fussball'
你会得到“1”-当使用“N”表示Unicode时,两个字符串被认为是相同的-为什么会这样,我还不知道(现在)
要查找服务器的默认排序规则,请使用
SELECT SERVERPROPERTY('Collation')
要查找数据库中给定列的排序规则,请使用以下查询:
select *
from op.tag
where tag = 'fussball'
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'
这不是一个解释行为的答案,但可能是相关的: 在这个问题上,我学会了使用
Latin1_General_Bin
将避免大多数排序规则的怪癖
奖金问题(答案?)@ScottCher
私下向我指出,
是由字符串文字引起的
“fussball”被视为varchar。
此查询不返回结果:
select 1
where 'fußball' = cast('fussball' as nvarchar)
选择1,其中“fußball”=
cast('fussball'作为nvarchar)
这里您要处理的是SQL Server数据类型优先规则,如中所述。始终使用更高优先级的类型进行比较:
当一个操作符将两个
不同数据类型的表达式,
数据类型优先级规则
指定具有
较低优先级转换为
具有较高优先级的数据类型
由于nvarchar的优先级高于varchar,因此示例中的比较将使用nvarchar类型,因此它实际上与
select 1完全相同,其中N'fußball'=N'fussball'
(即使用Unicode类型)。我希望这也能清楚地说明为什么上一个案例不返回任何行。在SQL Server上使用什么排序规则?您使用的语言和区域设置是什么?@marc_的一切都是默认的美国安装。我认为这是拉丁语1\u General\u CS\u AS?@marc\u的默认排序规则设置为SQL\u拉丁语1\u General\u CP1\u CI\u AS。此服务器可能是从Sql server 2000升级而来的。但仍然对这种行为感到困惑!谢谢我编辑了一个更直接的链接,并引用了文章的相关部分。