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

本文介绍了一种使用SQL函数fun_get_chinese_c_cnt筛选合法中文姓名的方法,该方法能够准确判断姓名字段中是否只含有1-4个中文汉字,并排除字母、数字及标点符号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上个星期接了个有关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.   双字节的字符也包含中文符号,日文等等。

 

 

### SQL 模糊查询使用方法 在 SQL 查询中,`LIKE` 是一种用于执行模糊匹配的关键字。通过 `LIKE` 和通配符的组合,可以灵活地筛选符合条件的数据记录。 #### 常见的通配符及其功能 1. **百分号 (`%`)** 表示零个或多个任意字符的占位符。它可以用来匹配字符串的一部分或者整个字符串[^3]。 2. **下划线 (`_`)** 表示单个字符的占位符。每次只匹配一个字符。 3. **方括号 (`[]`)** 方括号内的字符集合表示可选范围。例如 `[abc]` 将匹配任何单独的一个字母 a、b 或 c[^1]。 4. **脱字符 (`^`)** 当放置于方括号内部的第一个位置时,表示排除指定范围外的内容。例如 `[^a-z]` 将匹配除小写字母以外的所有字符。 --- #### 实现模糊查询的具体语法结构 基本形式如下所示: ```sql SELECT column_name(s) FROM table_name WHERE column_name LIKE pattern; ``` 其中 `pattern` 参数定义了需要匹配的模式,通常由固定文本和通配符组成[^2]。 --- #### 特殊情况处理 如果待查询字段本身含有特殊符号 `%` 或 `_`,则可以通过转义机制解决此问题。具体做法是在这些特殊字符前加上转义字符 `\` 并设置 ESCAPE 子句指明该转义标志的意义[^5]。例如: 假设表中有列名为 `name` 的一条记录存储值为 `"100%"` ,如果我们希望精确找到这条记录而不是其他包含子串 “%” 的条目,则应编写如下语句: ```sql SELECT * FROM my_table WHERE name LIKE '100\%' ESCAPE '\'; ``` 对于 ORACLE 数据库环境下的动态参数绑定场景,推荐采用字符串连接操作构建最终表达式以规避潜在异常风险[^4]: ```sql SELECT * FROM MESSAGE WHERE DESCRIPTION LIKE '%' || #{description} || '%'; ``` --- ### 示例代码片段 以下是几个实际应用中的例子展示如何利用上述理论完成不同类型的模糊检索需求: - 查找所有姓氏开头为 "张" 的人员名单: ```sql SELECT * FROM employees WHERE first_name LIKE '张%'; ``` - 寻找名字中间带有 "江" 字的所有员工: ```sql SELECT * FROM employees WHERE last_name LIKE '_江_%'; -- 这里假定至少有两个汉字构成的名字 ``` - 定位描述信息中含有确切短语 "%off" 的消息列表 (注意这里的 % 被视为普通字符而非通配符): ```sql SELECT * FROM messages WHERE content LIKE '%\%%off' ESCAPE '\'; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值