用排序规则特点计算汉字笔划和取得拼音首字母

来源:互联网 发布:噪声计算软件 编辑:程序博客网 时间:2024/05/10 09:50
       
    SQL SERVER的排序规则平时使用不是很多,也许不少初学者还比较陌生,但有      
   
  一个错误大家应是经常碰到:     SQL     SERVER数据库,在跨库多表连接查询时,若两数据      
   
  库默认字符集不同,系统就会返回这样的错误:           
    
                                       
                                              “无法解决     equal     to     操作的排序规则冲突。”      
   
       
   
  一.错误分析:      
   
    这个错误是因为排序规则不一致造成的,我们做个测试,比如:      
   
  create     table     #t1(      
   
  name     varchar(20)     collate     Albanian_CI_AI_WS,              
   
  value     int)      
   
       
   
  create     table     #t2(      
   
  name     varchar(20)     collate     Chinese_PRC_CI_AI_WS,                      
   
  value     int     )      
   
       
   
  表建好后,执行连接查询:      
   
       
   
  select     *     from     #t1     A     inner     join     #t2     B     on     A.name=B.name          
   
       
   
  这样,错误就出现了:      
   
       
   
                                              服务器:     消息     446,级别     16,状态     9,行     1      
   
                                              无法解决     equal     to     操作的排序规则冲突。      
   
    要排除这个错误,最简单方法是,表连接时指定它的排序规则,这样错误就      
   
  不再出现了。语句这样写:      
   
       
   
  select     *          
   
  from     #t1     A     inner     join     #t2     B          
   
  on     A.name=B.name     collate     Chinese_PRC_CI_AI_WS      
   
       
   
       
   
  二.排序规则简介:      
   
       
   
                  什么叫排序规则呢?MS是这样描述的:"在     Microsoft     SQL     Server     2000     中,      
   
  字符串的物理存储由排序规则控制。排序规则指定表示每个字符的位模式以及存      
   
  储和比较字符所使用的规则。"      
   
    在查询分析器内执行下面语句,可以得到SQL SERVER支持的所有排序规则。      
   
       
   
      select     *     from     ::fn_helpcollations()          
   
       
   
  排序规则名称由两部份构成,前半部份是指本排序规则所支持的字符集。      
   
  如:      
   
    Chinese_PRC_CS_AI_WS          
   
  前半部份:指UNICODE字符集,Chinese_PRC_指针对大陆简体字UNICODE的排序规则。      
   
  排序规则的后半部份即后缀     含义:          
   
    _BIN     二进制排序          
   
    _CI(CS)     是否区分大小写,CI不区分,CS区分      
   
    _AI(AS)     是否区分重音,AI不区分,AS区分         
   
    _KI(KS)     是否区分假名类型,KI不区分,KS区分       
   
                  _WI(WS)     是否区分宽度     WI不区分,WS区分       
   
       
   
  区分大小写:如果想让比较将大写字母和小写字母视为不等,请选择该选项。      
   
  区分重音:如果想让比较将重音和非重音字母视为不等,请选择该选项。如果选择该选项,      
   
                                      比较还将重音不同的字母视为不等。      
   
  区分假名:如果想让比较将片假名和平假名日语音节视为不等,请选择该选项。      
   
  区分宽度:如果想让比较将半角字符和全角字符视为不等,请选择该选项      
   
       
   
           
   
  三.排序规则的应用:      
   
    SQL     SERVER提供了大量的WINDOWS和SQLSERVER专用的排序规则,但它的应用往往      
   
  被开发人员所忽略。其实它在实践中大有用处。      
   
       
   
    例1:让表NAME列的内容按拼音排序:      
   
       
   
  create     table     #t(id     int,name     varchar(20))      
   
  insert     #t     select     1,'中'      
   
  union     all     select     2,'国'      
   
  union     all     select     3,'人'      
   
  union     all     select     4,'阿'      
   
       
   
  select     *     from     #t     order     by     name     collate     Chinese_PRC_CS_AS_KS_WS          
   
  drop     table     #t      
   
  /*结果:      
   
  id                                         name                                                                          
   
  -----------     --------------------          
   
  4                                             阿      
   
  2                                             国      
   
  3                                             人      
   
  1                                             中      
   
  */      
   
       
   
    例2:让表NAME列的内容按姓氏笔划排序:      
   
       
   
  create     table     #t(id     int,name     varchar(20))      
   
       
   
  insert     #t     select     1,'三'      
   
  union     all     select     2,'乙'      
   
  union     all     select     3,'二'      
   
  union     all     select     4,'一'      
   
  union     all     select     5,'十'      
   
  select     *     from     #t     order     by     name     collate     Chinese_PRC_Stroke_CS_AS_KS_WS              
   
  drop     table     #t      
   
  /*结果:      
   
  id                                         name                                                                          
   
  -----------     --------------------          
   
  4                                             一      
   
  2                                             乙      
   
  3                                             二      
   
  5                                             十      
   
  1                                             三      
   
  */      
   
       
   
  四.在实践中排序规则应用的扩展      
   
    SQL     SERVER汉字排序规则可以按拼音、笔划等排序,那么我们如何利用这种功能      
   
  来处理汉字的一些难题呢?我现在举个例子:      
   
       
   
            用排序规则的特性计算汉字笔划      
   
       
   
    要计算汉字笔划,我们得先做准备工作,我们知道,WINDOWS多国汉字,UNICODE目前      
   
  收录汉字共20902个。简体GBK码汉字UNICODE值从19968开始。      
   
    首先,我们先用SQLSERVER方法得到所有汉字,不用字典,我们简单利用SQL语句就      
   
  可以得到:      
   
       
   
  select     top     20902     code=identity(int,19968,1)     into     #t     from     syscolumns     a,syscolumns     b      
   
       
   
  再用以下语句,我们就得到所有汉字,它是按UNICODE值排序的:      
   
       
   
    select     code,nchar(code)     as     CNWord     from     #t          
   
       
   
    然后,我们用SELECT语句,让它按笔划排序。      
   
       
   
  select     code,nchar(code)     as     CNWord          
   
  from     #t          
   
  order     by     nchar(code)     collate     Chinese_PRC_Stroke_CS_AS_KS_WS,code      
   
       
   
  结果:      
   
  code                                 CNWord          
   
  -----------     ------          
   
  19968                             一      
   
  20008                             丨      
   
  20022                             丶      
   
  20031                             丿      
   
  20032                             乀      
   
  20033                             乁      
   
  20057                             乙      
   
  20058                             乚      
   
  20059                             乛      
   
  20101                             亅      
   
  19969                             丁      
   
  ..........      
   
       
   
            从上面的结果,我们可以清楚的看到,一笔的汉字,code是从19968到20101,从小到大排,但到      
   
  了二笔汉字的第一个字“丁”,CODE为19969,就不按顺序而重新开始了。有了这结果,我们就可以轻      
   
  松的用SQL语句得到每种笔划汉字归类的第一个或最后一个汉字。      
   
  下面用语句得到最后一个汉字:      
   
       
   
  create     table     #t1(id     int     identity,code     int,cnword     nvarchar(2))      
   
       
   
  insert     #t1(code,cnword)      
   
  select     code,nchar(code)     as     CNWord         from     #t          
   
  order     by     nchar(code)     collate     Chinese_PRC_Stroke_CS_AS_KS_WS,code      
   
       
   
       
   
  select     A.cnword          
   
  from     #t1     A          
   
  left     join     #t1     B     on     A.id=B.id-1     and     A.code<B.code          
   
  where     B.code     is     null      
   
  order     by     A.id      
   
       
   
  得到36个汉字,每个汉字都是每种笔划数按Chinese_PRC_Stroke_CS_AS_KS_WS排序规则排序后的      
   
  最后一个汉字:      
   
       
   
  亅阝马风龙齐龟齿鸩龀龛龂龆龈龊龍龠龎龐龑龡龢龝齹龣龥齈龞麷鸞麣龖龗齾齉龘      
   
       
   
    上面可以看出:“亅”是所有一笔汉字排序后的最后一个字,“阝”是所有二笔汉字排序后的最后      
   
  一个字......等等。      
   
    但同时也发现,从第33个汉字“龗(33笔)”后面的笔划有些乱,不正确。但没关系,比“龗”笔划      
   
  多的只有四个汉字,我们手工加上:齾35笔,齉36笔,靐39笔,龘64笔      
   
       
   
  建汉字笔划表(TAB_HZBH):      
   
  create     table     tab_hzbh(id     int     identity,cnword     nchar(1))      
   
  --先插入前33个汉字      
   
  insert     tab_hzbh      
   
  select     top     33     A.cnword          
   
  from     #t1     A          
   
  left     join     #t1     B     on     A.id=B.id-1     and       
    
 
原创粉丝点击