SQL Server中窄小的不间断空间比较失败

时间:2017-10-26 00:56:38

标签: sql-server string-comparison unicode-string

至少在SQL Server 2012和2016中,在等式比较中会忽略Narrow No-Break Space字符(NNBSP,Unicode 8239)。例如,采用以下两个查询,比较字符串“AB”和“A B”。第一个有“普通”,ASCII字符32个空格;第二个使用NNBSP。

-- Do not equal, as expected
SELECT *
  FROM (SELECT N'AB' NoSpaces) NoSpaces,
       (SELECT N'A   B' NormalSpaces) NormalSpaces
WHERE NoSpaces.NoSpaces = NormalSpaces.NormalSpaces

-- Do equal, which is unexpected
SELECT *
  FROM (SELECT N'AB' NoSpaces) NoSpaces,
       (SELECT N'A' + NCHAR(8239) + NCHAR(8239) + NCHAR(8239) + N'B' NNBSpaces) NNBSpaces
WHERE NoSpaces.NoSpaces = NNBSpaces.NNBSpaces   

其他一些字符串函数会忽略NNBSP,例如LIKE和CHARINDEX。 LIKE与equals具有相同的结果,CHARINDEX返回0,表示找不到该字符。

然而,其他功能如LEN和SUBSTRING确实承认它们的存在。

在研究上述每个函数时,我发现当前的校对可能是字符串比较的一个因素。我当前的排序规则是SQL_Latin1_General_CP1_CI_AS,但我已经尝试了所有“SQL_Latin1_General”排序规则,所有这些排序规则都有相同的结果。

任何人都可以提供有关为何发生这种情况的任何见解吗?

1 个答案:

答案 0 :(得分:1)

这是因为美国英语SQL_Latin1_General_CP1_CI_AS的默认SQL Server排序规则无法正确处理NNBSP Unicode字符比较。

从SQL Server 2008及更新版本开始,有更新的“Latin1”排序规则,其名称中包含“_100”。使用任何这些较新的排序规则,我观察到的问题都不存在。

根据MSDN(我通过this answer找到),这些较新的排序规则有许多更新和更正的功能。仅基于其描述,我认为纠正该问题的变化是:

  

加权已添加到以前非加权的字符,这些字符可以进行相同的比较。

如果有人有任何其他见解,我很想听听他们。