C# NET和T-SQL之间的字符串比较差异?

C# NET和T-SQL之间的字符串比较差异?,c#,sql,sql-server,string,comparison,C#,Sql,Sql Server,String,Comparison,在我编写的一个测试用例中,SQL server/.NET CLR之间的字符串比较方式似乎不同 此C代码: string lesser = "SR2-A1-10-90"; string greater = "SR2-A1-100-10"; Debug.WriteLine(string.Compare("A","B")); Debug.WriteLine(string.Compare(lesser, greater)); 将输出: -1 1 Less Than 此SQL Server代码:

在我编写的一个测试用例中,SQL server/.NET CLR之间的字符串比较方式似乎不同

此C代码:

string lesser =  "SR2-A1-10-90";
string greater = "SR2-A1-100-10";

Debug.WriteLine(string.Compare("A","B"));
Debug.WriteLine(string.Compare(lesser, greater));
将输出:

-1
1
Less Than
此SQL Server代码:

declare @lesser varchar(20);
declare @greater varchar(20);

set @lesser =  'SR2-A1-10-90';
set @greater = 'SR2-A1-100-10';

IF @lesser < @greater
    SELECT 'Less Than';
ELSE
    SELECT 'Greater than';
为什么不同

在SQL中,您使用了varchar,它基本上是受排序规则约束的ASCII,排序规则将给出-before 0 在C语言中,所有字符串都是Unicode UTF xx c与UCS-2 SQL Server之间的细微差别是相当棘手的

编辑:

我发得太快了

我在SQL Server 2008上获得了比排序规则Latin1\u General\u CI\u更高的性能

编辑2:

我也会尝试选择ASCII。。。快跑。例如,如果SQL代码段曾经出现在Word文档中,-150不是我复制到SQL Server中用于从浏览器中测试您的问题的-45。请参阅=CP1=SQL Server行话


编辑3:参见Martin Smith的答案:这两个排序规则具有不同的排序顺序。

除了gbn的答案之外,您还可以使用C中的CompareOptions.StringSort或使用StringComparation.Ordinal使它们的行为相同。这会将符号视为出现在字母数字符号之前,因此-<0

但是,Unicode与ASCII没有任何解释,因为ASCII代码页的十六进制代码被逐字翻译为Unicode代码页:-是002D 45,而0是0030 48

目前的情况是,.NET默认使用语言排序,这是基于非顺序排序和指定或当前文化对各种符号应用的权重。例如,这种语言算法允许在排序的单词列表中,拼写有重音的简历紧跟在拼写没有重音的简历之后出现,因为在e之后和f之前都给出了分数顺序。它还允许将合作紧密地放在一起,因为破折号符号的权重较低;它仅在对按该顺序出现的位、位和位移位等字进行排序时,作为绝对的最终分界线起作用

严格按照Unicode值进行所谓的顺序排序,不管是否区分大小写,都会产生非常不同的结果,有时甚至是不合逻辑的结果,因为在ASCII/Unicode顺序中,字母的变体通常出现在基本的未修饰拉丁字母表之后,而符号出现在它之前。例如,é在z之后,因此单词resume、rosin、ruble、résumé将按该顺序排序。位元,位元移位,位元,位元将按顺序排序,因为撇号排在第一位,后面是破折号,然后是字母e,然后是字母s。从自然语言的角度来看,这两种方法似乎都不符合逻辑。

这是正确的

Windows排序规则(例如Latin1_General_CI_AS)使用Unicode类型的排序规则。SQL排序规则没有


这导致连字符在两者之间的处理方式有所不同。

关于为什么会发生这种情况,已经有一些很好的答案,但我确信其他人只想知道C代码,以便按照与SQL server相同的顺序迭代集合。我发现以下作品效果最好。Ordinal绕过了连字符问题,而IgnoreCase似乎也反映了SQL server的默认设置

Debug.WriteLine(string.Compare(lesser, greater, StringComparison.OrdinalIgnoreCase));

你是否考虑了案件敏感性?案件都是一样的。区别在于它们如何将“0”处理为“-”。我认为这是一个Unicode问题。编辑:也许不是。对我来说,SQL Server代码返回的值大于。您正在测试的数据库中的默认排序规则是什么?如果@lesser<@greater collate Latin1\u General\u CI\u AS给出的排序规则大于。如果@lesser<@greater校对SQL\u Latin1\u General\u CP1\u CI\u AS给的也比我少。好的,是的。如果我手动指定排序规则,我会得到相同的结果。啊,我明白了。当我使用nvarchar20时,我得到的大于。我用varchar得到的。您的DB排序规则与服务器排序规则不同吗?代码页仅影响字符数>127,否?很酷。通过使用CompareOption.StringSort,我可以使用当前数据库排序规则设置运行测试。@gbn-技术上是。C似乎也是排序错误的;没有StringSort,符号字符位于字母数字之后。我将从fn_helpcollations中编辑.select*,其中名称(如“%SQL_Latin1_General_CP1_CI_AS%”或名称=“Latin1_General_CI_AS”)使用CP 1252进行非unicode排序。我敢肯定。。我也这么做了。。。不,没有。。