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升级而来的。但仍然对这种行为感到困惑!谢谢我编辑了一个更直接的链接,并引用了文章的相关部分。