SQL Server 2005中varchar()和nvarchar()之间奇怪的排序差异

5

有人能解释一下这个吗:

SELECT 
  CASE WHEN CAST('iX' AS nvarchar(20)) 
      > CAST('-X' AS nvarchar(20)) THEN 1 ELSE 0 END,
  CASE WHEN CAST('iX' AS varchar(20)) 
      > CAST('-X' AS varchar(20)) THEN 1 ELSE 0 END

Results: 0 1

SELECT 
  CASE WHEN CAST('i' AS nvarchar(20)) 
      > CAST('-' AS nvarchar(20)) THEN 1 ELSE 0 END,
  CASE WHEN CAST('i' AS varchar(20)) 
      > CAST('-' AS varchar(20)) THEN 1 ELSE 0 END

结果:1 1

在第一个查询中,nvarchar() 的结果不是我期望的,但是去掉 X 后,nvarchar() 的排序就按照预期进行。

(我的原始查询使用了 ''N'' 文字语法来区分 varchar()nvarchar(),而不是 CAST(),得到了相同的结果。)

数据库的排序设置为 SQL_Latin1_General_CP1_CI_AS


快速跟进:在我的情况下,“-”仅用作某些复杂文本的排序代码的填充字符。我将其替换为“!”现在它可以正常工作了。 - richardtallent
2个回答

9
在比较Unicode文本时,连字符会被特殊处理。Unicode比较使用“字典顺序”,忽略连字符。而在非Unicode文本比较中则不是这样。比较 -XiX 就像比较 XiX 一样,所以 -X(左侧)更大。当比较“-”和“i”时,就像比较“”和“i”一样,因此“i”(右侧)更大。
从MSDN中得知:“SQL排序规则用于对非Unicode数据排序的结果与任何由Microsoft Windows操作系统提供的排序例程都不兼容;但是,Unicode数据的排序与Windows排序规则的特定版本是兼容的。由于非Unicode数据和Unicode数据的比较规则不同,所以使用SQL排序规则时,对于相同字符的比较可能会出现不同的结果,具体取决于底层数据类型。例如,如果使用SQL排序规则“SQL_Latin1_General_CP1_CI_AS”,则非Unicode字符串'a-c'小于字符串'ab',因为连字符(“-”)被排序为一个单独的字符,位于“b”之前。然而,如果将这些字符串转换为Unicode并进行相同的比较,则认为Unicode字符串N'a-c'大于N'ab',因为Unicode排序规则使用忽略连字符的“单词排序”方式。”
SQL语句:SELCT body From MSDN_Articles WHERE url IN ("http://support.microsoft.com/kb/322112")

1
一个好问题!
经过调查,我发现这个问题与连字符和撇号有关。您的示例表现出与“-X”相同的“奇怪”行为。
我不能因为这里有答案而得到荣誉: SQL排序和连字符

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接