所有归类下包含相同长度整数的字符串的数字排序顺序

时间:2014-06-17 06:01:13

标签: sql sql-server tsql collation

可以安全地假设SQL Server中的所有排序规则都会给出&#34;期望的&#34; (即数字)对包含相同长度的整数的字符串的排序顺序?例如,假设@text仅包含非负整数([0-9]+),以下代码段是否可用于确保该值不会超出int范围,或者可能存在某些范围整理@text <= '2147483647'给出意想不到的结果?

IF LEN(@text) BETWEEN 1 AND 9 
OR LEN(@text) = 10 AND @text <= '2147483647'
-- ...

不会有可变长度比较的情况(例如'2' < '11'),所以请不要解决这个问题。

4 个答案:

答案 0 :(得分:3)

SQL Server排序规则不会保证有关编码的任何内容。它们是从字符的二进制表示到通常理解的字符的映射。

为此,我认为相关概念是&#34;代码页&#34;:

  

代码页

     

代码页是给定脚本的有序字符集,其中   数字索引或代码点值与每个索引相关联   字符。 Windows代码页通常称为字符   设置或charset。代码页用于提供支持   不同Windows使用的字符集和键盘布局   系统区域设置。所有Windows Server 2008 Unicode归类都是Unicode   5.0基于

&#34;命令&#34;这件事是这个问题的一部分。排序确定字符是否是#34;当然&#34;为数字订购。

所以,归类的概念并不要求数字是自然排序的。

那就是说,我不知道任何数字'0' - '9' 自然排序的排序规则。在Unicode标准中,数字是自然排序的。我想不出为什么有人会创造这样的整理。所以,在实践中,如果存在这样的校对,我会非常非常惊讶。而且,如果确实如此,它可能不符合Unicode,因此在SQL Server中不可用。

在实践中,不存在这样的整理,或者至少没有这种整理被广泛使用。排序规则不能保证自然排序,但它是Unicode字符集的一部分。您可以非常安全地假设所有排序规则都具有自然的数字排序,但理论上可以创建一个具有非自然数字排序的字符集。

答案 1 :(得分:2)

ORDER BY CASE WHEN ISNUMERIC(YourColumn) = 1 THEN Cast(YourColumn as Decimal(38,0)) ELSE null End

答案 2 :(得分:1)

就像我在评论中所说的那样,我认为你不会找到所有归类所有归类排序数字相同的硬文档,因为这不是整理的要求。但是假设/期望这样是合理的。我想不出一个单一的用例,我不希望数字排序相同。

有点难看但是全部测试了 第一个选择只创建选择
然后复制粘贴以运行输出作为选择
可能有一种方法可以在循环中执行此操作我无法使用整理来变量

没有失败这个简单的'54321'&lt; '22222'或N'22222'&lt; N'22221'为我测试

SELECT 'SELECT ''' + name + ''' where  ''54321'' < ''22222'' or N''22222'' < N''22221'' COLLATE ' + name FROM sys.fn_helpcollations() WHERE name NOT LIKE 'SQL%';

set nocount on 
SELECT 'Albanian_BIN' where  '54321' < '22222' or N'22222' < N'22221' COLLATE Albanian_BIN
SELECT 'Albanian_BIN2' where  '54321' < '22222' or N'22222' < N'22221' COLLATE Albanian_BIN2
SELECT 'Albanian_CI_AI' where  '54321' < '22222' or N'22222' < N'22221' COLLATE Albanian_CI_AI
SELECT 'Albanian_CI_AI_WS' where  '54321' < '22222' or N'22222' < N'22221' COLLATE Albanian_CI_AI_WS
SELECT 'Albanian_CI_AI_KS' where  '54321' < '22222' or N'22222' < N'22221' COLLATE Albanian_CI_AI_KS
SELECT 'Albanian_CI_AI_KS_WS' where  '54321' < '22222' or N'22222' < N'22221' COLLATE Albanian_CI_AI_KS_WS
SELECT 'Albanian_CI_AS' where  '54321' < '22222' or N'22222' < N'22221' COLLATE Albanian_CI_AS

回复您的评论

  

不幸的是,详尽的测试是不可行的,不是因为   排序数量,但由于字符串比较的数量   需要为每个整理进行。整理允许团体   要一起考虑的字符(例如“Mac”和“Mc”)。因此,'11'   &LT; “22”不需要给出与“12”相同的结果。 '22'。在我的情况下,我会   我需要为每个校对运行10 ^ 10个测试,就像我正在处理的那样   10位数字符串。

  • “Mac”和“Mc”有什么关系?国家问题是“不会有可变长度比较的情况(例如'2'&lt; '11'),所以请不要解决这个问题。”
  • 你觉得你需要测试所有10位数的字符串组合吗?
    因此,如果您测试了所有4位数组合,您会害怕位置7和8位中的两位数可能表现不同吗? 真的,如果你是那么担心,那么即使你发现文件中所有排序规则必须排序数字相同,这并不意味着他们正确实施。
  • 如果您对准确性敏感,那么为什么转换为数字超出范围?我得到你的问题并且你得到了赏金,但可能会问用例是什么?

我要做的是所有5位数的随机顺序表和所有4位数的随机顺序表(所以你有奇数和偶数)。 对每个排序规则进行排序并与已知良好排序进行比较 即使是中档服务器,这也会在4-8小时内完成。 这个问题有5天的赏金。

答案 3 :(得分:1)

可以安全地假设SQL Server中的所有排序规则都会给出&#34;期望的&#34; (即数字)对包含相同长度的整数的字符串的排序顺序? =是

...或者可能会有一些整理,其中@text&lt; =&#39; 2147483647&#39;出乎意料的结果? =无