在第二次尝试之后,当我使用异常处理程序时,仍然得到ORA-04068(包的现有状态已被丢弃)

时间:2017-02-10 09:38:10

标签: oracle plsql exception-handling

我有以下测试设置:

create or replace PACKAGE pkg_state
AS
   FUNCTION get_variable RETURN VARCHAR2;
END pkg_state;
/

create or replace PACKAGE BODY pkg_state
AS
   g_pkg_variable NUMBER(10) := 2; --testa

   FUNCTION get_variable
   RETURN VARCHAR2
   AS
   BEGIN
      RETURN 'FALSE ';
   END get_variable;

END pkg_state;
/

这里是测试电话:

set serveroutput on;
DECLARE
 v_ReturnValue  VARCHAR2(500);
BEGIN
  v_ReturnValue := PKG_STATE.get_variable();
  DBMS_OUTPUT.PUT_LINE('v_ReturnValue = ' || v_ReturnValue);
 exception when others then 
    DBMS_OUTPUT.PUT_LINE('ERROR');
    --raise;
END;

如果我运行此程序并在另一个会话中更改包,我将收到错误ORA-04068 - >预期

但是,如果我再次运行它(不再更改包),它将再次失败(并且之后的所有尝试)!

如果我重新加载错误(删除“raise;”的注释),一切都按预期工作:第一次错误;第二次它起作用。

我认为它会在第二次尝试时始终有效。当我“吞下”错误时为什么不这样做?永远不要读这个具体问题。

这似乎使得无法捕获错误并尝试再次拨打电话而用户没有注意到任何错误。 (DB 11.2.0.4)

2 个答案:

答案 0 :(得分:0)

Oracle将包的编译实例保存在每个会话的会话内存中。如果包无效,则重新加载。

因此,需要传播此错误(引发)来清理无效的包。

尝试忽略包变量的无效状态是不好的做法。

答案 1 :(得分:0)

要处理此类问题,只需从异常块重新运行代码:

DECLARE
 v_ReturnValue  VARCHAR2(500);
BEGIN
  v_ReturnValue := PKG_STATE.get_variable();
  DBMS_OUTPUT.PUT_LINE('v_ReturnValue = ' || v_ReturnValue);
 exception when others then
    DBMS_OUTPUT.PUT_LINE('ERROR');
     v_ReturnValue := PKG_STATE.get_variable();
  DBMS_OUTPUT.PUT_LINE('v_ReturnValue = ' || v_ReturnValue);
END;