Mat*_*ell 12 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));
Run Code Online (Sandbox Code Playgroud)
将输出:
-1
1
Run Code Online (Sandbox Code Playgroud)
这个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';
Run Code Online (Sandbox Code Playgroud)
将输出:
Less Than
Run Code Online (Sandbox Code Playgroud)
为什么不同?
除了gbn的答案之外,您可以通过在C#中使用CompareOptions.StringSort(或使用StringComparison.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".从"自然语言"的角度来看,这些都不符合逻辑.