註意Vietnamese_CI_AS排序規則下的特殊字元大小敏感問題 最近,在SQL Server中遇到了Vietnamese_CI_AS排序規則的特殊字元的大小寫敏感問題,是的,你沒有看錯,這句話並沒有語病(DBA老司機懂的)。遇到這個特殊情況的時候,我也大跌眼鏡,顛覆我的一些常識,OK,閑話少說... ...
註意Vietnamese_CI_AS排序規則下的特殊字元大小敏感問題
最近,在SQL Server中遇到了Vietnamese_CI_AS排序規則的特殊字元的大小寫敏感問題,是的,你沒有看錯,這句話並沒有語病(DBA老司機懂的)。遇到這個特殊情況的時候,我也大跌眼鏡,顛覆我的一些常識,OK,閑話少說,我們來演示一下這個特殊場景下出現的特殊情況。
準備測試環境:
伺服器排序規則(Server Collation) : Latin1_General_CI_AS
資料庫排序規則(Database Collation) : Vietnamese_CI_AS
註意,只有在這個特定排序規則下才會出現這個問題,準備好了測試環境後,我們先簡單聊幾句關於排序規則的知識,SQL Server裡面的排序規則其實是包含了字元集和排序規則兩樣東西,不像MySQL,字元集和排序規則概念和設置分開。如果你想查看某個排序規則對應的字元集,那麼就可用下麵的SQL語句查看。如下截圖所示:
SELECT COLLATIONPROPERTY('Vietnamese_CI_AS', 'CodePage') AS CodePage ,
COLLATIONPROPERTY('Vietnamese_CI_AS', 'ComparisonStyle') AS ComparisonStyle ,
COLLATIONPROPERTY('Chinese_PRC_CI_AS', 'CodePage') AS CodePage ,
COLLATIONPROPERTY('Chinese_PRC_CI_AS', 'ComparisonStyle') AS ComparisonStyle ,
COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'CodePage') AS CodePage ,
COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'ComparisonStyle') AS ComparisonStyle
Code Page |
Language |
|
932 |
Japanese |
日語 |
936 |
Simplified Chinese |
簡體中文 |
949 |
Korean |
韓文 |
950 |
Traditional Chinese |
繁體中文 |
1258 |
Vietnamese |
越南語 |
從上可以看到Chinese_PRC_CI_AS的編碼為936,如果對編碼比較熟悉的就很清楚,但是可能也有一些對這個不太瞭解。下麵簡單述說一下,
所謂代碼頁(code page)就是針對一種語言文字的字元編碼。例如GBK的code page是CP936 ,BIG5的code page是CP950,GB2312的code page是CP20936。
GBK是國家標準GB2312基礎上擴容後相容GB2312的標準。GBK的文字編碼是用雙位元組來表示的,即不論中、英文字元均使用雙位元組來表示,為了區分中文,將其最高位都設定成1。GBK包含全部中文字元,是國家編碼,通用性比UTF8差,不過UTF8占用的資料庫比GBK大。
UTF-8:Unicode TransformationFormat-8bit,允許含BOM,但通常不含BOM。是用以解決國際上字元的一種多位元組編碼,它對英文使用8位(即一個位元組),中文使用24位(三個位元組)來編碼。UTF-8包含全世界所有國家需要用到的字元,是國際編碼,通用性強。UTF-8版本雖然具有良好的國際相容性,但中文需要比GBK/BIG5版本多占用50%的資料庫存儲空間。
排序規則的後半部份即尾碼 含義:
_BIN 指定使用向後相容的二進位排序順序。
_BIN2 指定使用 SQL Server 2005 中引入的碼位比較語義的二進位排序順序。
_Stroke 按筆劃排序
_CI(CS) 是否區分大小寫,CI不區分,CS區分(case-insensitive/case-sensitive)
_AI(AS) 是否區分重音,AI不區分,AS區分(accent-insensitive/accent-sensitive)
_KI(KS) 是否區分假名類型,KI不區分,KS區分(kanatype-insensitive/kanatype-sensitive)
_WI(WS) 是否區分全半形, WI不區分,WS區分(width-insensitive/width-sensitive)
好了,簡單概述了一些關於編碼和字元集的知識。那麼我們來看看Vietnamese_CI_AS的Code Page為1258,這個是越南語言的一個字元集,很多人可能沒有用過這個,不過沒有關係。那麼我們先來看看問題。準備測試環境和數據,如下所示
USE TEST;
GO
CREATE TABLE TEST (name NVARCHAR(12));
INSERT INTO TEST
SELECT N'lienht' UNION ALL
SELECT N'LienHT' UNION ALL
SELECT N'LienHt'
SELECT * FROM TEST WHERE name ='lienHt';
SELECT * FROM TEST WHERE name ='lienht'
SELECT * FROM TEST WHERE name ='LIenht'
SELECT * FROM TEST WHERE name ='LIeNht'