Arabic_100_CS_AS_KS_WS_SC_UTF8 和 Latin1_General_100_CS_AS_KS_WS_SC_UTF8 有什麼區別?
從 SQL 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
using和Latin1_General_100_CS_AS_KS_WS_SC_UTF8
as collation之間有什麼區別嗎?
是的,所有
_UTF8
排序規則都使用程式碼頁 65001,因為這是UTF-8 的程式碼頁。您甚至可以通過以下方式在 DOS / 命令視窗中使用 65001:chcp 65001
儘管並非所有程序和字型都可以與它無縫協作。
對於
_UTF8
排序規則,程式碼頁不受文化(即Latin1_General
vsArabic
)的控制,_UTF8
因為程式碼頁指示用於VARCHAR
數據的特定 8 位編碼(即 8 位字元數據)。對於非 Unicode 8 位編碼,文化通常與作為字元集的程式碼頁相關聯(例如,Latin1 是程式碼頁 Windows-1252,它在 128-255 範圍內的字元與作為程式碼的 Windows-1255 不同希伯來語頁面)。但是對於 UTF-8,它是8 位編碼,用於單數、無所不包的字元集,即 Unicode。至於
Arabic_100_CS_AS_KS_WS_SC_UTF8
和Latin1_General_100_CS_AS_KS_WS_SC_UTF8
去之間的差異,它實際上只是對各種字元進行排序和比較的特定文化規則。當然,這兩種語言並沒有真正共享任何字元,但是在某些程式碼點的處理方式上仍然存在差異。查看“Windows Server 2008 排序權重表”文件(據我所知,這是版本
_100_
排序規則的主要依據),我找不到這兩個排序規則之間的任何排序/比較差異。因此,就行為而言,它們可能是相同的。但是,在它們仍然具有不同的 LCID(區域設置/文化標識符)的意義上它們並不相同,因此將它們的值轉換為非 UTF8VARCHAR
可能會導致數據失去/損壞,以及查看排序規則的任何程序/功能確定某些其他行為可能表現不同。話雖如此,我確實找到了使用烏爾都語排序規則時阿拉伯字元行為差異的範例,因為這些排序規則確實對預設排序權重進行了一些修改(9 在“Windows Server 2008 排序權重表”文件中註冊) .
查看“Teh Marbuta”字元(U+0629),它在預設表(即用於美國英語/Latin1 的表)中的權重為 29,其排序權重低於“Peheh”字元(U +06A6),預設權重為 137。41 表示字元在哪個“腳本”中,這兩個都是阿拉伯字元。但是,烏爾都語排序規則將“Teh Marbuta”(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
or對這兩個字元進行排序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 ة
最後,請記住,雖然很少遇到這種情況,但排序規則也會影響大寫/小寫映射。我相信這僅限於
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 İ İ İ