开始之前先上两个函数在官方得详细说明,因为之前开发函数之前没去官方看说明,直接百度看说明导致得坑,下面是官方文档得截图,官方明确说明这两个函数不支持
clob字段处理,但是我们可以通过隐式转换来实现,后面给出了本人写的对正常情况下varchar类型的支持以及相同功能下clob字段的实现方法:
测试数据如下:
------测试数据:
create table test_tab(id number,name varchar2(1000),loc clob);
insert into test_tab values(1,'','');
insert into test_tab values(2,' ,.·',' .,·');
insert into test_tab values(3,' '||chr(10)||chr(13),' '||chr(10)||chr(13));
insert into test_tab values(4,'sdf 东方闪电sdf123123 .·','sdf 东方闪电sdf123123 .·');
insert into test_tab values(5,'123','123');
insert into test_tab values(6,' 1 2 3',' 1 2 3');
insert into test_tab values(7,'1 2 3','1 2 3');
insert into test_tab values(8,'1 2 3ADSDSasdsASDAS','1 2 3ASDasdsASDAS');
insert into test_tab values(10,' 1 2 3ADSDSasdsASDAS',' 1 2 3ASDasdsASDAS');
insert into test_tab values(11,'sdf','sdf');
commit;
具体函数如下:
----处理varchar类型数据
create or replace function trans_varchar(p_char varchar2) return varchar2 DETERMINISTIC is
v_cache varchar2(4000);
v_char varchar2(4000):=to_single_byte(p_char);
cursor col is
select regexp_substr(v_char, '[^[:digit:],^[:punct:],^[:cntrl:],^[:blank:]]', 1, level) as ch,
regexp_substr(v_char, '[[:digit:]]', 1, level) as nu
from dual
connect by level <= case when length(p_char)>15 then 15 else length(p_char) end;
begin
v_cache := '';
for i in col loop
case
when asciistr(i.ch) between '\4E00' and '\9FA5' then
v_cache := v_cache || i.ch;
/* when i.ch between 0 and 9 then
v_cache:=v_cache||i.ch;*/
when i.ch between 'a' and 'z' then
v_cache := v_cache || i.ch;
when i.ch between 'A' and 'Z' then
v_cache := v_cache || i.ch;
else
v_cache := v_cache || i.nu;
end case;
end loop;
if v_cache is null then
return null;
else
return rtrim(ltrim(rtrim(ltrim(rtrim(ltrim(trim(v_char),
chr(9)),
chr(9)),
chr(10)),
chr(10)),
chr(13)),
chr(13));
end if;
end trans_varchar;
/
----处理clob字段:
create or replace function trans_clob(p_char clob) return clob DETERMINISTIC is
v_cache varchar2(4000);
v_char clob:=to_single_byte(dbms_lob.substr(p_char));
cursor col is
select regexp_substr(v_char, '[^[:digit:],^[:punct:],^[:cntrl:],^[:blank:]]', 1, level) as ch,
regexp_substr(v_char, '[[:digit:]]', 1, level) as nu
from dual
connect by level <= 15;
begin
v_cache := '';
for i in col loop
case
when asciistr(i.ch) between '\4E00' and '\9FA5' then
v_cache := v_cache || i.ch;
/* when i.ch between 0 and 9 then
v_cache:=v_cache||i.ch;*/
when i.ch between 'a' and 'z' then
v_cache := v_cache || i.ch;
when i.ch between 'A' and 'Z' then
v_cache := v_cache || i.ch;
else
v_cache := v_cache || i.nu;
end case;
end loop;
if v_cache is null then
return null;
else
return rtrim(ltrim(rtrim(ltrim(rtrim(ltrim(trim(v_char),
chr(9)),
chr(9)),
chr(10)),
chr(10)),
chr(13)),
chr(13));
end if;
end trans_clob;
/