Sql server 为什么SQL拉丁字母1\u General\u CP1\u CI\u作为排序号在下划线之前签名?

Sql server 为什么SQL拉丁字母1\u General\u CP1\u CI\u作为排序号在下划线之前签名?,sql-server,sorting,unicode,collation,Sql Server,Sorting,Unicode,Collation,接下来,我惊奇地发现: DECLARE @SampleData TABLE (ANSI VARCHAR(50), UTF16 NVARCHAR(50)); INSERT INTO @SampleData (ANSI, UTF16) VALUES ('##MS_PolicyTsqlExecutionLogin##', N'##MS_PolicyTsqlExecutionLogin##'), ('_gaia', N'_gaia'); SELECT sd.ANSI AS [ANSI

接下来,我惊奇地发现:

DECLARE @SampleData TABLE (ANSI VARCHAR(50), UTF16 NVARCHAR(50));
INSERT INTO @SampleData (ANSI, UTF16) VALUES 
    ('##MS_PolicyTsqlExecutionLogin##', N'##MS_PolicyTsqlExecutionLogin##'),
    ('_gaia', N'_gaia');

SELECT sd.ANSI AS [ANSI-SQL_Latin1_General_CP1_CI_AS]
FROM   @SampleData sd
ORDER BY sd.ANSI COLLATE SQL_Latin1_General_CP1_CI_AS ASC;

SELECT sd.UTF16 AS [UTF16-SQL_Latin1_General_CP1_CI_AS]
FROM   @SampleData sd
ORDER BY sd.UTF16 COLLATE SQL_Latin1_General_CP1_CI_AS ASC;
结果:

ANSI-SQL_Latin1_General_CP1_CI_AS
-------------------------------------
##MS_PolicyTsqlExecutionLogin##
_gaia

UTF16-SQL_Latin1_General_CP1_CI_AS
-------------------------------------
##MS_PolicyTsqlExecutionLogin##
_gaia

根据“”,当Unicode结果的顺序应该相反时。为什么会是这种情况?

第一件事:相关问题----还没有被证明是完全正确的;-)

撇开这些相关信息不谈,让我们看一下各个部分:

  • VARCHAR
    字段与
    将SQL\u拉丁1\u常规\u CP1\u CI\u校对为

    这将主要基于ASCII值进行排序,对于字母字符,将基于代码页1(也称为代码页1252)中定义的规则进行排序和比较

    #
    字符是ASCII代码35,而
    字符是ASCII代码95。这些不是字母字符,所以我们应该假设在执行
    ASC
    结束顺序时,它们将以
    作为第一位进行排序,就像您在这里所做的那样

  • NVARCHAR
    字段与
    将SQL\u Latin1\u General\u CP1\u CI\u校对为

    这将根据Unicode规则进行排序。Unicode中没有代码页,但可能存在文化差异,这些差异会覆盖默认的排序规则和顺序。而且,为了让事情变得更有趣,基本规则和特定于区域性/区域设置的覆盖都可以(而且确实)随着时间的推移而改变。软件供应商实施新版本标准的速度并不总是那么快。这与在不同时间点实现不同W3C规范的各种浏览器没有什么不同。SQL Server的主要更新是2008版,它引入了
    100
    系列排序规则。SQL Server 2012引入了
    90
    100
    系列的变体,以
    \u SC
    结尾,用于处理补充字符(即UCS-2集合之外的其余UTF-16字符)

    回到刚才提到的内容,每个语言环境/区域性都可以指定对任何规则(而不仅仅是排序规则)的覆盖。当前版本28(仅在4天前发布!!)在美国地区具有以下内容(位于:)

    
    
    阅读新语法并不是很容易,但我认为他们没有对这些标点符号进行重新排序。如果你去他们的网站,点击下面的4个链接(从左上方开始)作为“标点符号”,除了一个字符外,它肯定会在所有字符前面列出“\ux”

    如果我们回顾几个版本,我们会发现(位于:):

    
    A.
    !"#$%&'()*+,-./
    0123456789:;?@
    ABCDEFGHIJKLMNOPQRSTUVWXYZ
    [\]^_`
    abcdefghijklmnopqrstuvwxyz
    {|}~
    
    现在,它确实看起来像是他们重新排序的,并且顺序与ASCII值相同

    如果将URL更改为指向版本24,则看起来与当前版本28 XML一样

    根据这里找到的发布日期,第24版于2013年发布,远远晚于
    100
    系列排序规则的编码


  • SQL Server没有实现默认的Unicode排序算法规则,这是正确的,但他使用Unicode排序的代码页是错误的。包含了Unicode排序是如何真正实现的详细说明。

    您有SQL Server使用UCA或CLDR规则的说法的来源吗?您可以链接到POSIX规则,但为什么Windows会将这些规则用于Latin1(这是一个不同的字符集)?而且,您给出的两个POSIX命令是相同的,它们只是。理论不错,但我认为它实际上并不正确。结果是,版本化的排序表是在发布的。与之相比,它看起来像排序顺序(对于所讨论的两个字符)是相同的。因此,要么SQL Server使用的是旧版本,要么肯定发生了其他情况。@Gili不清楚Microsoft所说的“Unicode排序规则”是什么意思“规则。另一件需要记住的事情是UCA规则是为定制而设计的。@Gili我现在时间不多,但是:仔细看看这两个排序表,你会发现没有下划线;-)。在浏览器中执行Crtl-F测试。不适用于“en”区域设置。正如我所说,SQL Server使用的是旧版本。我从未说过使用了v23,只是我看到了至少从v24开始的符号变化。但从发布日期来看,如果SQL Server可以使用的Windows最新排序规则(100系列)在2008年发布,那么CLDR版本必须已经存在,可能是2006年的v1.4或2007年的v1.5。以后再说@一二三 我的时间很短,但是:虽然不是决定性的证据(我会寻找更好的证据),但在备注部分的末尾有一个指示:。您有索赔的来源吗?;-)我发现有两次提到它,但都是在2004年和2005年。另外,我现在只研究Unicode处理,因此只有一个字符集。