`

oracle 判断字段中的中文的方法

阅读更多

判断字段中的中文的方法,与oracle的字符集有关,
AL32UTF8字符集下:中文length() 的结果为3,ascii()的结果为8位,asciistr()可以判断
eg:
select * from v$nls_parameters where parameter = 'NLS_CHARACTERSET';
1 NLS_CHARACTERSET AL32UTF8
select length('靠') from dual;
1 1
select lengthb('靠') from dual;
1 3
select asciistr('/\)(-=!@#$%^&*~中文字符') from dual;
1 /\)(-=!@#$%^&*~\4E2D\6587\5B57\7B26
select asciistr('\') from dual;
1 \
select ascii('哦') from dual;
1 15045542
ZHS16GBK字符集下:
select * from v$nls_parameters where parameter = 'NLS_CHARACTERSET';
1 NLS_CHARACTERSET ZHS16GBK
select length('靠') from dual;
1 1
select lengthb('靠') from dual;
1 2
select asciistr('/\)(-=!@#$%^&*~中文字符') from dual;
1 /\)(-=!@#$%^&*~\4E2D\6587\5B57\7B26
select instr(asciistr('/)(-=!@#$%^&*~★ABC'),'\') from dual;
1 15
select asciistr('\') from dual;
1 \
select ascii('哦') from dual;
1 50614

可以自定义函数来实现一个对字段值中是否包含有中文的判断(如邮件地址验证等)

select instr(asciistr('/\)(-=!@#$%^&*~中文字符'),'\') from dual;
如果instr的结果大于0,则包含中文或者一些特殊字符,为0则不含中文。
(但是没有能够排除掉'\'的干扰,不能区别汉字和特殊字符)


比较好的方法(摘抄):

从表里提取汉字, 需要考虑字符集, 不同的字符集汉字的编码有所不同
这里以GB2312为例, 写一函数准确地从表里提取简体汉字.

假设数据库字符集编码是GB2312, 环境变量(注册表或其它)的字符集也是GB2312编码
并且保存到表里的汉字也都是GB2312编码的

那么也就是汉字是双字节的,且简体汉字的编码范围是
B0A1 - F7FE
换算成10进制就是
B0 A1 F7 FE
176,161 - 247,254

我们先看一下asciistr函数的定义
Non-ASCII characters are converted to the form. \xxxx, where xxxx represents a UTF-16 code unit.
但是这并不表示以 "\" 开始的字符就是汉字了

举例如下
SQL> select * from test;

NAME
--------------------
,啊OO10哈
你好aa
大家好aa/
☆大海123
★ABC

这里第5条记录有一个实心的五角星
然后用asciistr函数转换一下试试
SQL> select name,asciistr(name) from test;

NAME ASCIISTR(NAME)
-------------------- ----------------------
,啊OO10哈 ,\554AOO10\54C8
你好aa \4F60\597Daa
大家好aa/ \5927\5BB6\597Daa/
☆大海123 \2606\5927\6D77123
★ABC \2605ABC

我们看到最后一条记录的实心五角星也是 "\"开头的
此时我们就不能用asciistr(字段)是否存在 "\" 来判断是否含有汉字了.

我的函数如下,基本思路是判断字符的编码是否在GB2312规定的汉字编码范围之内
--------------------------------------------------------------------------------
create or replace function get_chinese(p_name in varchar2) return varchar2 as
v_code varchar2(30000) := '';
v_chinese varchar2(4000) := '';
v_comma pls_integer;
v_code_q pls_integer;
v_code_w pls_integer;
begin
if p_name is not null then
select replace(substrb(dump(p_name, 1010),
instrb(dump(p_name, 1010), 'ZHS16GBK:')),
'ZHS16GBK: ',
'')
into v_code
from dual
where rownum = 1;
for i in 1 .. length(p_name) loop
if lengthb(substr(p_name, i, 1)) = 2 then
v_comma := instrb(v_code, ',');
v_code_q := to_number(substrb(v_code, 1, v_comma - 1));
v_code_w := to_number(substrb(v_code,
v_comma + 1,
abs(instrb(v_code, ',', 1, 2) -
v_comma - 1)));
if v_code_q >= 176 and v_code_q <= 247 and v_code_w >= 161 and
v_code_w <= 254 then
v_chinese := v_chinese || substr(p_name, i, 1);
end if;
v_code := ltrim(v_code, '1234567890');
v_code := ltrim(v_code, ',');
end if;
v_code := ltrim(v_code, '1234567890');
v_code := ltrim(v_code, ',');
end loop;
return v_chinese;
else
return '';
end if;
end;
/
--------------------------------------------------------------------------------
好,现在来执行一些语句
SQL> select * from test;

NAME
--------------------
,啊OO10哈
你好aa
大家好aa/
☆大海123
★ABC

5 rows selected.

1. 列出有汉字的记录
SQL> select name from test where length(get_chinese(name))>0;

NAME
--------------------
,啊OO10哈
你好aa
大家好aa/
☆大海123

4 rows selected.

2. 列出有汉字的记录,并且只列出汉字

SQL> select get_chinese(name) from test where length(get_chinese(name))>0;

GET_CHINESE(NAME)
---------------------------------------------------------------------------
啊哈
你好
大家好
大海

4 rows selected.


需要说明的是GB2312共有6763个汉字,即72*94-5=6763
我这里是计算72*94,没有减去那5个,那五个是空的。等查到了再减去
============

改写这个函数,可以提取非汉字或者汉字
该函数有两个参数,第一个表示要提取的字符串,第二个是1,表示提取汉字,是非1,表示提取非汉字
--------------------------------------------------------------------------------
create or replace function get_chinese(p_name in varchar2,
p_chinese in varchar2)
return varchar2 as
v_code varchar2(30000) := '';
v_chinese varchar2(4000) := '';
v_non_chinese varchar2(4000) := '';
v_comma pls_integer;
v_code_q pls_integer;
v_code_w pls_integer;
begin
if p_name is not null then
select replace(substrb(dump(p_name, 1010),
instrb(dump(p_name, 1010), 'ZHS16GBK:')),
'ZHS16GBK: ',
'')
into v_code
from dual
where rownum = 1;
for i in 1 .. length(p_name) loop
if lengthb(substr(p_name, i, 1)) = 2 then
v_comma := instrb(v_code, ',');
v_code_q := to_number(substrb(v_code, 1, v_comma - 1));
v_code_w := to_number(substrb(v_code,
v_comma + 1,
abs(instrb(v_code, ',', 1, 2) -
v_comma - 1)));
if v_code_q >= 176 and v_code_q <= 247 and v_code_w >= 161 and
v_code_w <= 254 then
v_chinese := v_chinese || substr(p_name, i, 1);
else
v_non_chinese := v_non_chinese || substr(p_name, i, 1);
end if;
v_code := ltrim(v_code, '1234567890');
v_code := ltrim(v_code, ',');
else
v_non_chinese := v_non_chinese || substr(p_name, i, 1);
end if;
v_code := ltrim(v_code, '1234567890');
v_code := ltrim(v_code, ',');
end loop;
if p_chinese = '1' then
return v_chinese;
else
return v_non_chinese;
end if;
else
return '';
end if;
end;


/--------------------------------------------------------------------------------
SQL> select * from a;

NAME
--------------------
我们啊、
他(艾呀)是★们
他的\啊@

SQL> select get_chinese(name,1) from a;

GET_CHINESE(NAME,1)
-----------------------------------------
我们啊
他艾呀是们
他的啊

SQL> select get_chinese(name,0) from a;

GET_CHINESE(NAME,0)
-----------------------------------------

()★
\@

SQL>

分享到:
评论

相关推荐

    Oracle中如何用SQL检测字段是否包括中文字符

    有一个同事的数据迁移程序有个问题,没有考虑中文编码字符,由于迁移的表有几千万数据,但是有中文的记录集很少,问我能否找出有中文内容的记录数。首先我想到的是采用检测每个字节ASCII的方式,这样的话需要写一个...

    Oracle中强大的中文处理

    有着强大的中文处理作用,既方便,又快捷,轻松的省去原来重新新建一个数据库的方法。

    Oracle判断指定列是否全部为数字的sql语句

    代码如下: select nvl2(translate(name,’\1234567890 ‘, ‘\... 您可能感兴趣的文章:oracle 重置序列从指定数字开始的方法详解ORACLE数据库中怎么求除数字、字母之外的非中文字符的正则表达式Oracle中判断字段是否为

    oracle使用instr或like方法判断是否包含字符串

    使用contains谓词有个条件,那就是列要建立索引,本节主要介绍了oracle使用instr或like方法判断是否包含字符串,需要的朋友可以参考下

    oracle数据库经典题目

    1.在多进程Oracle实例系统中,进程分为用户进程、后台进程和服务进程。 2.标准的SQL语言语句类型可以分为:数据定义语句(DDL)、数据操纵语句(DML)和数据控制语句(DCL)。 3.在需要滤除查询结果中重复的行时,必须...

    供应彩信二次开发接口,彩信开发平台,研发各种软件功能

    6.应用系统可通过读取MSG_Sentbox和MSG_Failedbox表中的信息来判断彩信/短信发送是否成功 接收彩信过程 1.手机用户向GPRS彩信设备发送了一条彩信 2.彩信系统将收到的“彩信通知“保存到MSG_Inbox中,并控制GPRS...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part1

    实例115 判断字符串中是否存在指定子串 146 2.9 正则表达式 147 实例116 验证电话号码的格式是否正确 147 实例117 验证Email地址格式是否正确 148 实例118 验证IP地址是否有效 149 实例119 统计关键字的查询结果 150...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    实例115 判断字符串中是否存在指定子串 146 2.9 正则表达式 147 实例116 验证电话号码的格式是否正确 147 实例117 验证Email地址格式是否正确 148 实例118 验证IP地址是否有效 149 实例119 统计关键字的查询结果 150...

    Java面试宝典2020修订版V1.0.1.doc

    21、数组中有没有length()方法,String中有没有length()方法? 18 23、final, finally, finalize的区别。 18 24、‘==’和equals的区别? 18 25、JAVA中Object类中有哪些常用方法? 19 26、heap和stack有什么区别...

    会议管理系统数据库设计文档.doc

    在oracle数据库设计中,一 般来说,对于定长的字符数据字段,取字符类型(char),对于不定长的,取变长字符类 型(varchar)。 2.对于以分类形式出现的字段,建议不使用字符类型,而使用数字类型。如:货物 是否配送为...

    asp.net知识库

    通过反射调用類的方法,屬性,字段,索引器(2種方法) ASP.NET: State Server Gems 完整的动态加载/卸载程序集的解决方案 从NUnit中理解.NET自定义属性的应用(转载) 如何在.NET中实现脚本引擎 (CodeDom篇) .NET的插件...

    Java面试宝典2010版

    7、char型变量中能不能存贮一个中文汉字?为什么? 8、用最有效率的方法算出2乘以8等於几? 9、请设计一个一百亿的计算器 10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 11、"=="和...

    C#编程经验技巧宝典

    73 &lt;br&gt;0106 如何获得一个字符串中数字的长度 74 &lt;br&gt;0107 如何获得字符串中数字或字母的长度 74 &lt;br&gt;0108 如何获得字符串中某个数字的位置 75 &lt;br&gt;0109 获得字符串中汉字的个数 76 &lt;br&gt;0110...

    最新Java面试宝典pdf版

    7、char型变量中能不能存贮一个中文汉字?为什么? 9 8、用最有效率的方法算出2乘以8等於几? 9 9、请设计一个一百亿的计算器 9 10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 11 11、"==...

    Java面试笔试资料大全

    7、char型变量中能不能存贮一个中文汉字?为什么? 9 8、用最有效率的方法算出2乘以8等於几? 9 9、请设计一个一百亿的计算器 9 10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 11 11、"==...

    JAVA面试宝典2010

    7、char型变量中能不能存贮一个中文汉字?为什么? 9 8、用最有效率的方法算出2乘以8等於几? 9 9、请设计一个一百亿的计算器 9 10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 11 11、"==...

    Java面试宝典-经典

    7、char型变量中能不能存贮一个中文汉字?为什么? 9 8、用最有效率的方法算出2乘以8等於几? 9 9、请设计一个一百亿的计算器 9 10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 11 11、"==...

    java面试题大全(2012版)

    7、char型变量中能不能存贮一个中文汉字?为什么? 9 8、用最有效率的方法算出2乘以8等於几? 9 9、请设计一个一百亿的计算器 9 10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 11 11、"==...

    Java面试宝典2012版

    7、char型变量中能不能存贮一个中文汉字?为什么? 9 8、用最有效率的方法算出2乘以8等於几? 9 9、请设计一个一百亿的计算器 9 10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 11 11、...

Global site tag (gtag.js) - Google Analytics