ORACLE blob字段使用replace,blob转char缓冲区对于 CLOB 到 CHAR 转换或 BLOB 到 RAW 转换而言太小

我们在使用oracle时会面对各种类型的字段,有时需要不同字段类型的转换,比如blob转char

常规替换

函数解析:

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 转换而言太小 (实际: 3744, 最大: 2000)

to_char方法将clob类型转换成varchar类型出了问题,oracle中varchar最大的长度是4000。把clob大文本类型直接转换成varcahr类型时,如果clob的长度小于4000,没有超过varchar的最大值,不会出问题,一旦超过4000就会报错

这时候就需要使用函数将blob转为varchar2

上述内容及转化方法参数:oracle修改Blob类型数据,批量更新数据做字符替换_oracle blob转字符串_Tine.的博客-CSDN博客

到这里你以为问题就解决了嘛!当然没有,大佬的csdn中提到的两个函数C2B和Blob_To_Varchar以及存储过程更新多数据的方法可以解决大多数的问题。但是由于blob字段在oracle中的最大长度是2G,所以一条blob字段的数据可以超级大超级大。

当blob字段中的数据达到32767个字符以上,上述的方法就会变得无效,你执行sql或存储过程后依旧会报:缓冲区对于 CLOB 到 CHAR 转换或 BLOB 到 RAW 转换而言太小

而我的客户给我展示的生产环境最大一条数据的字符数是140万多,在我两天不断的搜索和与做数据开发方面同事的研究下,得到了一个朴实无华且真实有效的方法。

首先,在原解决方法的基础上修改函数Blob_To_Varchar

-- 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 := 32767;
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));
--当转换出来的字符串乱码时,可尝试用注释掉的函数
--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;
    
Return V_Varchar1;
END Blob_To_Varchar;

原函数中的V_Buffer Pls_Integer是substr截取字符串的长度,通过循环截取每次截取4000长度的字符在将其转为Varchar2类型就是原函数的作用。

对函数的修改为将截取长度改为Varchar2字段的最大长度,并将循环移除,使函数每次固定截取转化32767的字符。

(当字段长度超过32767的时候,循环截取在第九次时会报错缓冲区不够等问题,报错语句是V_Varchar1 := V_Varchar1 || V_Varchar;)

如果你也是上面的报错,恭喜你我们错的都一样

当然朴实无华的方法就是编写多个函数分别的超长字段多个部分进行截取,在将他们拼接起来

update ceshi t
   set content = (C2B(to_clob((SELECT REPLACE(Blob_To_Varchar1(content),
                                           
                                             '2.2.2.2','1.1.1.1')
                               from ceshi a
                              where a.infoid = t.infoid)||
                              (SELECT REPLACE(Blob_To_Varchar2(content),
                                           
                                             '2.2.2.2','1.1.1.1')
                               from ceshi a
                              where a.infoid = t.infoid)
                    )))
where length(content) >32767

用这个方法你可以无限套娃,进行blob字段中超长字符的转化。

希望对你有所帮助!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值