从Server 2019开始,它支持UTF-8作为排序规则。然而,根据以下询问:
SELECT COLLATIONPROPERTY('Arabic_100_CS_AS_KS_WS_SC_UTF8', 'CodePage')
SELECT COLLATIONPROPERTY('Latin1_General_100_CS_AS_KS_WS_SC_UTF8', 'CodePage');都返回代码页65001,它是Windows中的Unicode。此外,所有新的_UTF8排序规则都使用代码页65001:
SELECT * FROM sys.fn_helpcollations() WHERE name LIKE '%_UTF8';使用Arabic_100_CS_AS_KS_WS_SC_UTF8和Latin1_General_100_CS_AS_KS_WS_SC_UTF8作为排序规则有什么不同吗?
发布于 2021-06-16 16:04:24
是的,所有_UTF8排序规则都使用代码页65001,因为这是UTF-8的代码页.您甚至可以通过以下方式在DOS / Command窗口中使用65001:
chcp 65001尽管并不是所有的程序和字体都能与它无缝地工作。
对于_UTF8排序规则,代码页不受区域性(即Latin1_General vs Arabic)的控制,也不受非_UTF8排序规则的控制,因为代码页指示用于VARCHAR数据的特定8位编码(即8位字符数据)。对于非Unicode 8位编码,区域性通常绑定到作为字符集的代码页(例如,Latin1是代码页Windows1252,它在128-255范围内具有与Windows1255不同的字符,后者是希伯来语的代码页)。但对于UTF-8,它是8位编码的单数,包括所有字符集,是Unicode.
就Arabic_100_CS_AS_KS_WS_SC_UTF8和Latin1_General_100_CS_AS_KS_WS_SC_UTF8之间的差异而言,它实际上只是用于对不同字符进行排序和比较的特定于文化的规则。当然,这两种语言并不真正共享任何字符,但在处理某些代码点方面仍然存在差异。
查看"Windows 2008排序权重表“文件(据我所知,这是_100_排序规则的主要基础),我找不到这两个排序规则之间的任何排序/比较差异。因此,它们在行为上可能是一样的。但是,它们并不相同,因为它们仍然具有不同的LCID (地区/区域性标识符),因此将它们的值转换为非UTF8 8 VARCHAR可能导致数据丢失/损坏,任何查看排序规则以确定其他行为的进程/功能都可能会有不同的行为。
尽管如此,我确实找到了一个使用Urdu排序规则时阿拉伯字符行为不同的例子,因为这些排序规则确实对默认排序权重进行了一些修改(在"Windows Server 2008排序权重表“文件中注册了9)。
查看"Teh“字符(U+0629),它在默认表中的权重为29 (即用于美式英语/Latin1的表),它的排序权重低于默认权重为137的"Peheh”字符(U+06A6)。41表示字符在哪个“脚本”中,这两个字符都是阿拉伯字符。然而,乌尔都语排序规则将"Teh“(U+0629)的排序权重修改为183,后者的排序权重高于"Peheh”(U+06A6),仍为137。
-- Default
0x0629 41 29 2 2 ;Arabic Teh Marbuta -- ة
0x06a6 41 137 2 2 ;Arabic Peheh -- ڦ
-- Urdu modifications
0x0629 41 183 2 2 ;Teh Marbuta -- ة如果我们使用Latin1_General_100_CS_AS_KS_WS_SC_UTF8或Arabic_100_CS_AS_KS_WS_SC_UTF8对这两个字符进行排序,我们应该得到默认的行为。而且,即使我们使用Yakut排序规则(它使用西里尔脚本并对默认排序权重进行了自己的修改),它也不会修改这些阿拉伯字符,因此它们的行为应该与使用Latin1_General或Arabic排序规则时相同:
SELECT *
FROM (VALUES (1, NCHAR(0x0629)), (2, NCHAR(0x06a6))) tmp(ID, TheChar)
ORDER BY tmp.[TheChar] COLLATE Latin1_General_100_CS_AS_KS_WS_SC_UTF8 ASC
SELECT *
FROM (VALUES (1, NCHAR(0x0629)), (2, NCHAR(0x06a6))) tmp(ID, TheChar)
ORDER BY tmp.[TheChar] COLLATE Arabic_100_CS_AS_KS_WS_SC_UTF8 ASC
SELECT *
FROM (VALUES (1, NCHAR(0x0629)), (2, NCHAR(0x06a6))) tmp(ID, TheChar)
ORDER BY tmp.[TheChar] COLLATE Yakut_100_CS_AS_KS_WS_SC_UTF8 ASC上面显示的所有三个查询都返回以下结果:
ID TheChar
1 ة
2 ڦ但是,当我们切换到Urdu排序规则时,这两个字符的顺序确实会改变:
SELECT *
FROM (VALUES (1, NCHAR(0x0629)), (2, NCHAR(0x06a6))) tmp(ID, TheChar)
ORDER BY tmp.[TheChar] COLLATE Urdu_100_CS_AS_SC_UTF8 ASC返回:
ID TheChar
2 ڦ
1 ة最后,请记住,虽然很少遇到这种情况,排序规则也会影响上/下-case映射。我认为,这仅限于Azeri_*和Turkish的排序规则,只适用于字母“i”和“i”(这些文化的大写字母“i”和小写字母“i”都是点缀的),但最好还是要意识到它的潜力:
SELECT UPPER(N'i' COLLATE Arabic_100_CS_AS_KS_WS_SC_UTF8) AS [Arabic],
UPPER(N'i' COLLATE Turkish_100_CS_AS_KS_WS_SC_UTF8) AS [Turkish],
UPPER(N'i' COLLATE Azeri_Cyrillic_100_CS_AS_KS_WS_SC_UTF8) AS [Azeri_Cyrillic],
UPPER(N'i' COLLATE Azeri_Latin_100_CS_AS_KS_WS_SC_UTF8) AS [Azeri_Latin];返回:
Arabic Turkish Azeri_Cyrillic Azeri_Latin
I İ İ İhttps://dba.stackexchange.com/questions/294387
复制相似问题