ORA-04068:已丢弃现有的包状态

时间:2016-05-19 07:22:48

标签: oracle stored-procedures plsql

我的包装程序看起来像这样:

Procedure A
BEGIN;
    Procedure B
    Procedure C
END;
/

过程B删除并重新创建过程C中使用的表。由于这个原因,我得到以下错误:

ERROR at line 1: 
ORA-04068: existing state of packages has been discarded ORA-04065: not executed, altered or dropped stored procedure "SCHEMA.PROCEDURE C" 
ORA-06508: PL/SQL: could not find program unit being called: "SCHEMA.PROCEDURE C" 
ORA-06512: at "SCHEMA.PROCEDURE A", line 4 
ORA-06512: at line 1

如何让这个程序运作?

3 个答案:

答案 0 :(得分:2)

所以你的proc在执行期间变得无效,这就是你需要重新编译过程C的原因。为了实现这一点,你可以调用动态SQL语句:

EXECUTE IMMEDIATE 'ALTER PROCEDURE my_procedure COMPILE';



Procedure_A IS
BEGIN;
    Procedure_B;
    EXECUTE IMMEDIATE 'ALTER PROCEDURE Procedure_C COMPILE';
    Procedure_C;
END;
/

答案 1 :(得分:1)

我建议使用动态SQL在过程C中调用DML。通过删除依赖项,不会使任何内容失效。这可能比动态重新编译代码或动态运行代码并捕获所有异常更可靠。

您可以在下面的示例代码中看到这一点。在过程C中注释掉第10行的静态SQL调用以复制错误。

drop table drop_me;
create table drop_me(id number);

create or replace procedure C is
    v_count number;
begin
    --Static SQL would fail with this error:
    --  ORA-04068: existing state of packages has been discarded
    --  ORA-04065: not executed, altered or dropped stored procedure "JHELLER.C"
    --  ORA-06508: PL/SQL: could not find program unit being called: "JHELLER.C"
    --  ORA-06512: at "JHELLER.A", line 4
    --  ORA-06512: at line 2
    --select count(*) into v_count from drop_me;

    --Dynamic SQL runs correctly:
    execute immediate 'select count(*) from drop_me' into v_count;
end;
/
create or replace procedure B is
begin
    execute immediate 'drop table drop_me purge';
    execute immediate 'create table drop_me(id number)';
end;
/
create or replace procedure A is
begin
    B;
    C;
end;
/
begin
    A;
end;
/

但我同意Alex Poole的观点,几乎可以肯定有一种更好的方法可以做到这一点,而无需删除和重新创建对象。我可以想到为什么DROPCREATE可能比TRUNCATEINSERT运行得更快的几个原因,但仅仅是因为一些奇怪的副作用,比如掉线不好表统计。更多地调查差异,你可能会找到真正的原因。

答案 2 :(得分:0)

你可以做类似的事情。

 begin 
   procedureB;
   begin 
     execute immediate 'begin procedureC; end;';
   exception when others then 
     execute immediate 'begin procedureC; end;';
   end;   
 end;