寻找"筛选中文汉字"的sql

上个星期接了个有关member数据质量处理的小项目,要求是根据会员的联系人名字,公司名,联系电话等信息,从DW中筛选出合法的会员来。

 

对于联系人名字筛选,要求是:

只能是包含1-4个中文汉字,名字可以有空格。不能包括字母数字已经标点符号等。

 

SQL> select * from v$nls_parameters where PARAMETER='NLS_CHARACTERSET';

 

PARAMETER                                                        VALUE

----------------------------------------------------------------

NLS_CHARACTERSET                                                 US7ASCII

 

 

解决方案:

 

中文汉字是双字节存储的,而字母数字以及标点符号等都是单字节的,所以,通过判断联系人里面每个字符是单字节还是多字节的,就知道它是否符合条件了。

 

同事已经写了一个统计有多少个汉字的函数,那么我写sql就方便多了。

 

create or replace function fun_get_chinese_c_cnt

(

 p_string          IN VARCHAR2

)

RETURN NUMBER IS

/*********************************************************************

*模块:

*频率:

*功能:判断字符串中汉字的个数

*作者:wzy

*时间:2009-03-24

*备注:

*********************************************************************/

     l_result               NUMBER;

     l_us7            NUMBER(3);      --US7ASCII编码下字符串长度

     l_str_us7          VARCHAR2(256) := p_string;  --ZHS16GBK编码下的keyword

     l_analyze_code1    VARCHAR2(3);    --双字节字符的第一字节的10进制编码

     i                INT;            --循环控制

BEGIN

     l_us7 := LENGTH(p_string);

     l_result:=0;

     i:=1;

     ------逐个字符分析KeyWord------

     WHILE i <= l_us7 LOOP

           ------获取字符的十进制编码------

           l_analyze_code1:=ascii(substr(l_str_us7,i,1));

           ------字符类型判断------

           IF(l_analyze_code1<128)THEN --单字节的情形

              i:= i+1;

           ELSE--双字节的情形

              i:=i+2;

              l_result:=l_result+1;

           END IF;

           --l_result:=l_result+1;

     END LOOP;--keyword分析完毕

     RETURN(l_result);

END ;

 

那么我现在只需要用 汉字的个数*2 = 字段值的长度 这个条件做筛选就OK,再考虑空格情况,这样就需要用这个条件之前把空格替换掉就行了,sql如下:

SELECT *

FROM cntmp.membertocompanytemp

WHERE --check first_name

(

            fun_get_chinese_c_cnt(REPLACE(TRIM(first_name), ' ', '')) * 2 = length(REPLACE(TRIM(first_name), ' ', ''))

            AND length(REPLACE(TRIM(first_name), ' ', '')) >= 2 --1个中文字

            AND length(REPLACE(TRIM(first_name), ' ', '')) <= 8   --4个中文字 

)

 

 

结:

1.   每个中文汉字占用两个字节,用dump()函数可以看到具体的ascii的值

2.   一般的而言,简体字的编码都大于128,而繁体字的第二个字节编码值小于128,所以如下语句都会查询到结果:

SELECT job_title, DUMP(job_title)

FROM cntmp.membertocompanytemp

WHERE regexp_like(job_title, '[a-zA-Z0-9]')

--job_title LIKE '%a%'

AND fun_get_chinese_c_cnt(REPLACE(TRIM(job_title), ' ', '')) * 2 = length(REPLACE(TRIM(job_title), ' ', ''));

我们刚好可以利用这一点筛选出包含繁体字的数据。

当然,也有极少数繁体字两个字节的编码都大于128的。

3.   双字节的字符也包含中文符号,日文等等。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值