SQL Server瞩目Vietnamese_CI_AS排序规则下之特殊字符大小敏感问题

注意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

 

 

SQL Server 1

 

 

 

 

 

 

 

 

 

 

 

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’

 

 

 

SQL Server 2

 

SQL Server 3

 

 

设若齐测试截图所示,只有N、H或NH的组合会出现大小写敏感问题,其它字符没有这种情景,测试的时候,确实是颠覆我的三观,相当之惊诧与不解,然后自己测试了不同排序规则,以及不同数据库版本,发现这个独自在服务器排序规则也Latin1_General_CI_AS,数据库排序规则吧Vietnamese_CI_AS,不管是SQL
Server 2008、SQL Server 2012、 SQL Server
2014都见面产出是问题。网上找并没过剩资料,并没有什么答案,猜测与Vietnamese的编码有关系,这个bug是同事在越南的种类遇到并发出来的。另外,在网上也发现产生相近的呼救
https://social.msdn.microsoft.com/forums/sqlserver/en-US/e634864a-13b5-49cd-a91d-0af38b5ce16c/tsql-like-1n
。遇到有这般场景的虽需要非常小心了。解决方案,服务器排序规则与数据库排序规则平等肯定可以免此问题,另外临时解决方案虽是在SQL语句被指定排序规则,如下所示:

 

 

 

SQL Server 4

相关文章