常规替换
函数解析
- utl_raw.cast_to_raw (blob字段) : 将blob字段转为字符串
- replace(string, str, tgt) : 替换函数, string中的str 替换成tgt
- utl_raw.cast_to_raw(string) : 将字符串转为raw类型
update 表 a set a.blob字段 = utl_raw.cast_to_raw ( replace ( utl_raw.cast_to_varchar2 ( a.blob字段 ), '目标字段', '要替换成的字段' ) ) where 条件
blob大数据替换
用上述方法blob数据过多时会出现以下报错:
ora-22835: 缓冲区对于 clob 到 char 转换或 blob 到 raw 转换而言太小 (实际: 4786, 最大: 2000)

to_char方法将clob类型转换成varchar类型出了问题,oracle中varchar最大的长度是4000。
把clob大文本类型直接转换成varcahr类型时,如果clob的长度小于4000,没有超过varchar的最大值,不会出问题,一旦超过4000就会报错
sql解决方法
1.将blob转换成clob
-- typecasts blob to clob (binary conversion)
-- blob转换为clob的方法
create or replace function c2b ( b in clob default empty_clob ( ) ) return blob is res blob;
b_len number := dbms_lob.getlength ( b );
dest_offset1 number := 1;
src_offset1 number := 1;
amount_c integer := dbms_lob.lobmaxsize;
blob_csid number := dbms_lob.default_csid;
lang_ctx integer := dbms_lob.default_lang_ctx;
warning integer;
begin
if b_len > 0 then
dbms_lob.createtemporary ( res, true );
dbms_lob.open ( res, dbms_lob.lob_readwrite );
dbms_lob.converttoblob ( res, b, amount_c, dest_offset1, src_offset1, blob_csid, lang_ctx, warning );
else
select empty_blob ( ) into res from dual;
end if;
return res;-- res is open here
end c2b;2.从clob转成varchar2
-- clob转成varchar2的方法
create or replace function blob_to_varchar ( blob_in in blob ) return clob is v_varchar varchar2 ( 32767 );
v_varchar1 varchar2 ( 32767 );
v_start pls_integer := 1;
v_buffer pls_integer := 4000;
begin
if dbms_lob.getlength ( blob_in ) is null
then return '';
end if;
v_varchar1 := '';
--return to_char(ceil(dbms_lob.getlength(blob_in) / v_buffer));
for i in 1..ceil ( dbms_lob.getlength ( blob_in ) / v_buffer )
loop
--当转换出来的字符串乱码时,可尝试用注释掉的函数
--v_varchar := utl_raw.cast_to_varchar2(utl_raw.convert(dbms_lob.substr(blob_in, v_buffer, v_start),'simplified chinese_china.zhs16gbk', 'american_the netherlands.utf8'));
v_varchar := utl_raw.cast_to_varchar2 ( dbms_lob.substr( blob_in, v_buffer, v_start ) );
v_varchar1 := v_varchar1 || v_varchar;
v_start := v_start + v_buffer;
end loop;
return v_varchar1;
end blob_to_varchar;3.编写sql
update 表名 set blob字段 = c2b ( to_clob( ( select replace ( blob_to_varchar ( blob字段 ), '要被替换的值', '替换值' ) from 表名 where 条件 ) ) ) where rp_code = 条件
多数据更新场景
用上述方法一次仅仅可更新一条数据,如果需要批量更新数据,则编写存储过程:
create or replace procedure update_content is
-- 定义游标(需要批量修改的数据)
cursor cur is select * from t_prescription_info;
begin
for temp in cur
loop
-- dbms_output.put_line ( temp.rp_code );
update t_prescription_info
set rp_content = c2b ( to_clob( ( select replace ( blob_to_varchar ( blob字段 ), '要被替换的值', '替换值' ) from t_prescription_info where rp_code = temp.rp_code ) ) )
where rp_code = temp.rp_code;
end loop;
end update_content;
-- 执行存储过程
begin
update_content;
end;总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论