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



我有以下测试设置:

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;"的评论(,一切按预期工作:第一次错误;第二次工作。

我认为它在第二次尝试时总是有效。为什么当我"吞下"错误时不这样做?永远不要阅读有关此特定问题的信息。

这似乎使得无法捕获错误并尝试再次进行调用,而用户没有注意到任何错误。(数据库 11.2.0.4(

Oracle 在每个会话的

会话内存中保留包的编译实例。如果包无效,则会重新加载。

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

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

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

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;

最新更新