我有以下测试设置:
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(
会话内存中保留包的编译实例。如果包无效,则会重新加载。
因此,需要传播此错误(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;