通过代码备份存储过程,package body 和表数据 并还原
Table data
--buckup table data
create table Table_BUCKUP as
(select * from Table1);
--roolback table data
drop table Table1;
create table Table1 as
(select * from Table_BUCKUP);
drop table Table_BUCKUP;
当表中存在long类型字段是会有异常 ORA-00997: 非法使用 LONG 数据类型, 遇到这种问题使用to_lob或或sys.dbms_metadata_util.long2varchar对数据进行转换,如下:
create table Table_BUCKUP as
(select to_lob(col) as C1 from Table1);
此时roolback 需要将lob转回到原来的类型了。
Package
--buck up DDL
Create table Package_BUCKUP
(name varchar(10),
script club
);
insert into Package_BUCKUP
value
select 'PKG1' name,dbms_metadata.get_ddl('PACKAGE','PackageName','SchemaName') script from dual;
--roolback DDL
由于EXECUTE IMMEDIATE 不能执行 club字段类型 可以将club转成varchar2或long再执行,9i以上版本的oracle中 varchar2再PL/SQL中最大值是32767 再schema中4000, 如果你的script不超过32767就不存在问题。
但是我得超过了最大值限制。 其实可以输出到文件,再执行。 有时间的时候我再试吧,经过沟通领导不需要通过script备份,领导想用pl/sqldeveloper得功能导出来备。
下面给出我失败的例子
PROCEDURE rollbacktest
IS
v_sql clob;
v_sql_long long;
tmp long;
tmp1 long;
TMP2 long;
TMP3 long;
TMP4 long;
TMP5 long;
TMP6 long;
TMP7 long;
TMP8 long;
TMP9 long;
TMP10 long;
TMP11 long;
TMP12 long;
TMP13 long;
TMP14 long;
TMP15 long;
TMP16 long;
TMP17 long;
TMP18 long;
TMP19 long;
TMP20 long;
TMP21 long;
TMP22 long;
TMP23 long;
TMP24 long;
TMP25 long;
TMP26 long;
TMP27 long;
TMP28 long;
TMP29 long;
TMP30 long;
TMP31 long;
TMP32 long;
TMP33 long;
TMP34 long;
TMP35 long;
TMP36 long;
TMP37 long;
TMP38 long;
TMP39 long;
TMP40 long;
TMP41 long;
TMP42 long;
TMP43 long;
TMP44 long;
TMP45 long;
TMP46 long;
TMP47 long;
TMP48 long;
TMP49 long;
TMP50 long;
TMP51 long;
TYPE ref0 IS REF CURSOR;
cur0 ref0;
v_count int;
v_interval int;
v_tmp_execu long;
v_tmp_swap long;
BEGIN
v_interval := 32767;
select script into v_sql from package_buckup where name = 'PAS_PKG';
OPEN cur0 FOR
select LEVEL - 1
from package_buckup
where name = 'PAS_PKG'
connect by LEVEL <= ceil(length(script) / v_interval);
LOOP
FETCH cur0
into v_count;
EXIT WHEN cur0%NOTFOUND;
dbms_output.put_line(to_char(v_count));
if v_count = 0 then
tmp := dbms_lob.substr(v_sql, v_interval, 1);
insert into package_debug values (tmp, sysdate, 'tmp', v_count);
else
tmp := tmp ||
dbms_lob.substr(v_sql, v_interval, (v_count * v_interval) + 1);
insert into package_debug values (tmp, sysdate, 'tmp', v_count);
end if;
if v_count = 0 then
TMP1 := TMP;
end if;
if v_count = 1 then
TMP2 := TMP;
end if;
if v_count = 2 then
TMP3 := TMP;
end if;
if v_count = 3 then
TMP4 := TMP;
end if;
if v_count = 4 then
TMP5 := TMP;
end if;
if v_count = 5 then
TMP6 := TMP;
end if;
if v_count = 6 then
TMP7 := TMP;
end if;
if v_count = 7 then
TMP8 := TMP;
end if;
if v_count = 8 then
TMP9 := TMP;
end if;
if v_count = 9 then
TMP10 := TMP;
end if;
if v_count = 10 then
TMP11 := TMP;
end if;
if v_count = 11 then
TMP12 := TMP;
end if;
if v_count = 12 then
TMP13 := TMP;
end if;
if v_count = 13 then
TMP14 := TMP;
end if;
if v_count = 14 then
TMP15 := TMP;
end if;
if v_count = 15 then
TMP16 := TMP;
end if;
if v_count = 16 then
TMP17 := TMP;
end if;
if v_count = 17 then
TMP18 := TMP;
end if;
if v_count = 18 then
TMP19 := TMP;
end if;
if v_count = 19 then
TMP20 := TMP;
end if;
if v_count = 20 then
TMP21 := TMP;
end if;
if v_count = 21 then
TMP22 := TMP;
end if;
if v_count = 22 then
TMP23 := TMP;
end if;
if v_count = 23 then
TMP24 := TMP;
end if;
if v_count = 24 then
TMP25 := TMP;
end if;
if v_count = 25 then
TMP26 := TMP;
end if;
if v_count = 26 then
TMP27 := TMP;
end if;
if v_count = 27 then
TMP28 := TMP;
end if;
if v_count = 28 then
TMP29 := TMP;
end if;
if v_count = 29 then
TMP30 := TMP;
end if;
if v_count = 30 then
TMP31 := TMP;
end if;
if v_count = 31 then
TMP32 := TMP;
end if;
if v_count = 32 then
TMP33 := TMP;
end if;
if v_count = 33 then
TMP34 := TMP;
end if;
if v_count = 34 then
TMP35 := TMP;
end if;
if v_count = 35 then
TMP36 := TMP;
end if;
if v_count = 36 then
TMP37 := TMP;
end if;
if v_count = 37 then
TMP38 := TMP;
end if;
if v_count = 38 then
TMP39 := TMP;
end if;
if v_count = 39 then
TMP40 := TMP;
end if;
if v_count = 40 then
TMP41 := TMP;
end if;
if v_count = 41 then
TMP42 := TMP;
end if;
if v_count = 42 then
TMP43 := TMP;
end if;
if v_count = 43 then
TMP44 := TMP;
end if;
if v_count = 44 then
TMP45 := TMP;
end if;
if v_count = 45 then
TMP46 := TMP;
end if;
if v_count = 46 then
TMP47 := TMP;
end if;
if v_count = 47 then
TMP48 := TMP;
end if;
if v_count = 48 then
TMP49 := TMP;
end if;
if v_count = 49 then
TMP50 := TMP;
end if;
--if mod(v_count+1,3) = 0 then
tmp := '';
end loop;
/*select length(tmp1 || tmp2 || tmp3 || tmp4 || tmp5 || tmp6 || tmp7 || tmp8 || tmp9 ||
tmp10 || tmp11 || tmp12 || tmp13 || tmp14 || tmp15 ||
tmp16 || tmp17 || tmp18 || tmp19 || tmp20 || tmp21) into v_count from dual;
dbms_output.put_line(v_count);*/
/*EXECUTE IMMEDIATE tmp1 || tmp2 || tmp3 || tmp4 || tmp5 || tmp6 || tmp7 || tmp8 || tmp9 ||
tmp10 || tmp11 || tmp12 || tmp13 || tmp14 || tmp15 ||
tmp16 || tmp17 || tmp18 || tmp19 || tmp20 || tmp21 ||
tmp22 || tmp23 || tmp24 || tmp25 || tmp26 || tmp27 ||
tmp28 || tmp29 || tmp30 || tmp31 || tmp32 || tmp33 ||
tmp34 || tmp35 || tmp36 || tmp37 || tmp38 || tmp39 ||
tmp40 || tmp41 || tmp42 || tmp43 || tmp44 || tmp45 ||
tmp46 || tmp47 || tmp48 || tmp49 || tmp50;*/
END backuptest;
Error: character string buffer too small