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

Posted

技术标签:

【中文标题】varchar() 和 nvarchar() 之间奇怪的 SQL Server 2005 排序规则差异【英文标题】:Weird SQL Server 2005 Collation difference between varchar() and nvarchar() 【发布时间】:2011-03-04 16:09:00 【问题描述】:

谁能解释一下:

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

结果: 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

【问题讨论】:

快速跟进:在我的情况下,“-”仅用作某些复杂文本的排序代码的填充字符。我把它换成了“!”现在可以正常使用了。 【参考方案1】:

在比较 unicode 文本时,会特别处理连字符。 Unicode 比较使用“字典顺序”,它忽略连字符。非 unicode 文本比较不是这种情况。

比较-XiX,就像比较XiX,所以左侧的-X 更大。 比较“-”和“i”时,就像比较“”和“i”一样,所以“i”,右边更大。

来自 MSDN,

SQL 排序规则的排序规则 非 Unicode 数据不兼容 提供的任何排序例程 微软视窗操作系统 系统;然而,排序 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 排序规则使用 忽略连字符的“单词排序”。

SELCT body From MSDN_Articles WHERE url IN("http://support.microsoft.com/kb/322112")

【讨论】:

【参考方案2】:

一个很好的问题!

四处挖掘,我发现问题与连字符和撇号有关。您的示例使用 '''X' 表现出与使用 '-X' 相同的“奇怪”行为。

我不能把找到答案的功劳归功于它,因为它就在这里: SQL Sorting and hyphens

【讨论】:

以上是关于varchar() 和 nvarchar() 之间奇怪的 SQL Server 2005 排序规则差异的主要内容,如果未能解决你的问题,请参考以下文章

SQLSERVER中nvarchar和varchar类型的区别是啥?

varchar和nvarchar区别

SQL中varchar和nvarchar有啥区别?

在现有 SQL Server 数据库上使用实体框架时禁用 VARCHAR 和 NVARCHAR 之间的转换

char , varchar和Nvarchar区别

SQLSERVER中nvarchar和varchar类型的区别是啥?