Oracle varchar2变成CLOB和BLOB

有2个表的字段为varchar2(4000)现在扩长度,但是再继续扩会报错,这已经达到varchar2的最大长度,所以计划将需要字段由varchar2变为blob;


目前2个表的字段类型
alter table TECHINFOA modify (TECHD VARCHAR2(4000));
alter table KNOWLEDGEP modify (PCONTENT VARCHAR2(4000));




方法一:通过utl_raw.cast_to_raw实现:



alter table TECHINFOA add TECHD_B blob;
update TECHINFOA set  TECHD_B=utl_raw.cast_to_raw( TECHD);
commit;
alter table TECHINFOA  drop colum TECHD;
alter table TECHINFOA rename TECHD_B to TECHD;


SQL> update TECHINFOA set  TECHD_B=utl_raw.cast_to_raw( TECHD);
update TECHINFOA set  TECHD_B=utl_raw.cast_to_raw( TECHD)
                                      *
第 1 行出现错误:
ORA-06502: PL/SQL: 数字或值错误 : raw variable length too long
ORA-06512: 在 "SYS.UTL_RAW", line 224




A RAW is limited to 2000 bytes 。但是该表中的值已经超过了2000,所以该方法不可行,


方法二:通过to_clob和dbms_lob解决



基本思想是先将varchar2 转换成 clob,再将clob转换为blob。




下是操作过程,用到的function会在后面给出:(写了2个function:C2B V2B,功能分别是将clob变为blob,将varchar2变了blob)


表TECHINFOA转换,用了functionC2B
alter table TECHINFOA add TECHD_B blob;
alter table TECHINFOA add TECHD_C clob;
update TECHINFOA set  TECHD_C=to_clob( TECHD);
update TECHINFOA set  TECHD_B=c2b(TECHD_c) ;
commit;
alter table TECHINFOA  drop column TECHD;
alter table TECHINFOA rename column TECHD_B to TECHD;
alter table TECHINFOA  drop column TECHD_C;




表KNOWLEDGEP转换,用了function V2B
alter table  KNOWLEDGEP add PCONTENT_B BLOB;
update KNOWLEDGEP set  PCONTENT_B=V2B( PCONTENT);
commit;
alter table  KNOWLEDGEP drop column PCONTENT;
alter table KNOWLEDGEP rename column PCONTENT_B to PCONTENT;


上面用到了两个不可函数,使用哪个都可以。




用到的2个function


function参考了:http://blog.youkuaiyun.com/wbo112/article/details/9041575


CREATE OR REPLACE FUNCTION C2B (c_clob IN CLOB default empty_clob())
   RETURN BLOB
IS
   b_blob            BLOB;
   b_len          number  := dbms_lob.getlength(c_clob) ;
   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 (b_blob, TRUE);
   DBMS_LOB.OPEN (b_blob, DBMS_LOB.lob_readwrite);
   DBMS_LOB.convertToBlob (b_blob,
                           c_clob,
                           amount_c,
                           dest_offset1,
                           src_offset1,
                           blob_csid,
                           lang_ctx,
                           warning
                          );
 else
   select   empty_blob()  into  b_blob  from  dual ;
  end if ;
   RETURN b_blob;
END C2B;




CREATE OR REPLACE FUNCTION V2B(l_var IN varchar2) RETURN BLOB IS
  c_clob   CLOB := to_clob(l_var);
  b_blob   BLOB;
  b_len    number := dbms_lob.getlength(c_clob);
  b_offset NUMBER := 1;
  c_offset NUMBER := 1;
  c_amount INTEGER := DBMS_LOB.lobmaxsize;
  b_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(b_blob, TRUE);
    DBMS_LOB.OPEN(b_blob, DBMS_LOB.lob_readwrite);
    DBMS_LOB.convertToBlob(b_blob,
                           c_clob,
                           c_amount,
                           b_offset,
                           c_offset,
                           b_csid,
                           lang_ctx,
                           warning);
  else
    select empty_blob() into b_blob from dual;
  end if;
  RETURN b_blob;
END V2B;



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值