更新blob字段的存储过程--转自XINFEI0803的博客

[sql]  view plain copy
  1. CREATE OR REPLACE PROCEDURE INVHL_UPDATE_BLOB_DATA(p_table_name      IN VARCHAR2,--表名  
  2.                                  p_blob_field_name IN VARCHAR2,--blob列名  
  3.                                  p_where_condition IN VARCHAR2,--主键  
  4.                                  p_id              IN VARCHAR2,--id  
  5.                                  p_blob_data       IN blob)--数据  
  6. /*表名table_name,  
  7.    clob字段名field_name  
  8.    确定要更新唯一记录的where条件p_where_condition  
  9.   传入的字符串变量P_clob_data*/  
  10.  IS  
  11.   v_lobloc       BLOB;--目标blob字段  
  12.   v_blob_data    blob;--作为接收参数的字段,参数变量不能直接拿来赋值  
  13.   v_amount       BINARY_INTEGER;--总长度  
  14.   v_query_string VARCHAR2(1000);--sql语句  
  15.   v_sub_length   binary_integer;--一次读取的最大长度,不超过32766  
  16.   v_sub_blob     blob;--一次读取的子串  
  17.   offset         binary_integer;--游标  
  18. BEGIN  
  19.   v_amount       := LENGTH(p_blob_data);  
  20.   v_blob_data    := p_blob_data;  
  21.   v_sub_length   := 32766;  
  22.   offset         :=1;  
  23.   v_query_string := 'SELECT ' || p_blob_field_name || ' FROM ' ||  
  24.                     p_table_name || ' WHERE ' || p_where_condition ||'='||p_id||  
  25.                     ' FOR UPDATE';  
  26.   dbms_output.put_line(v_query_string);  
  27.   --initialize buffer with data to be inserted or updated  
  28.   EXECUTE IMMEDIATE v_query_string--执行sql语句,将目标字段锁住,并且将目标字段赋值给v_lobloc,以待后续的操作  
  29.     INTO v_lobloc;  
  30.   
  31.   --from pos position, write 32766 varchar2 into lobloc  
  32.   
  33.       if v_amount > v_sub_length then   
  34.        while offset < v_amount loop --当游标小于最大值时,继续循环  
  35.             DBMS_LOB.read(p_blob_data, v_sub_length, offset,v_sub_blob);--把读到的内容放到v_sub_blob中  
  36.             DBMS_LOB.writeappend(v_lobloc, length(v_sub_blob), v_sub_blob);--写入v_lobloc,该变量已经在之前和sql语句绑定  
  37.             offset:=length(v_sub_blob)+offset;--游标移动  
  38.        end loop;  
  39.        else  
  40.             DBMS_LOB.writeappend(v_lobloc, v_amount, v_blob_data);--若是小于32766直接写入  
  41.     end if;  
  42.   commit;  
  43.     
  44. EXCEPTION  
  45.   WHEN OTHERS THEN  
  46.     ROLLBACK;  
  47. END;  

以上就是通用版的存储过程,根据表名、blob字段名、主键名称、当前id,源数据就可以实现将源数据存入目标字段的功能。需要注意以下几点:

1,源数据必须也是blob类型的,如果你需要将其他类型比如是varchar2存入,那么就把参数改了,过程之中也要做相应的更改,主要是类型。

2,DBMS_LOB.writeappend这个方法是用来追加的方法,也就是不会清空目标字段,而是直接把源数据追加到目标字段的末尾。如果是要覆盖之前的数据,就要在执行该过程之前进行一次update操作,如:

[sql]  view plain copy
  1. update jforum_posts_text pt    set pt.post_text = EMPTY_BLOB()   where pt.post_id = 8817;  

也就是把一个空数据插入到目标字段中,这样就实现了清空目标字段,然后在执行该过程,就实现了覆盖的功能。注意一点,执行update语句时别忘了where子句,否则所有的记录都被清空了。

3,当该过程被用在触发器中时(一般也是用在这里面),就要注意,触发器不允许用commit和rollback这样的语句,要去掉之后重新编译。

经过半下午的摸索,这个过程才基本可以满足要求,欢迎大家伙给予指教,能多多改进该过程,使其更具灵活性。

引用自XINFEI0803的博客:http://blog.csdn.net/xinfei0803/article/details/8660074

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值