有2个表的字段为varchar2(4000)现在扩长度,但是再继续扩会报错,这已经达到varchar2的最大长度,所以计划将需要字段由varchar2变为blob;
目前2个表的字段类型
alter table TECHINFOA modify (TECHD VARCHAR2(4000));
alter table KNOWLEDGEP modify (PCONTENT VARCHAR2(4000));
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,所以该方法不可行,
基本思想是先将varchar2 转换成 clob,再将clob转换为blob。
下是操作过程,用到的function会在后面给出:(写了2个function:C2B V2B,功能分别是将clob变为blob,将varchar2变了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;
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;
目前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;