开发人员修改一个包里一个过程,修改成功,并重新编译成功,在程序日志发现调用这个包报错ORA-06508: PL/SQL: 无法找到正在调用的程序单元
先如下验证:
打开数据库的一个会话创建一个包如下:
CREATE OR REPLACE PACKAGE SimplePkg AS
v_GlobalVar1 NUMBER := 1;
PROCEDURE UpdateVar;
END SimplePkg;
/
CREATE OR REPLACE PACKAGE BODY SimplePkg AS
PROCEDURE UpdateVar IS
vv number;
xx number;
BEGIN
v_GlobalVar1 := 7;
END UpdateVar;
END SimplePkg;
/
第一个会话:
PROD@dev>CREATE OR REPLACE PACKAGE SimplePkg AS
2 v_GlobalVar NUMBER := 1;
3 PROCEDURE UpdateVar;
4 END SimplePkg;
5 /
Package created.
PROD@dev>CREATE OR REPLACE PACKAGE BODY SimplePkg AS
2 PROCEDURE UpdateVar IS
3 BEGIN
4 v_GlobalVar := 7;
5 END UpdateVar;
6 END SimplePkg;
7 /
Package body created.
然后在打开第二个会话调用这个包:
BEGIN
simplePkg.UpdateVar;
END;
第二个会话:
PROD@dev>BEGIN
2 simplePkg.UpdateVar;
3 END;
4 /
PL/SQL procedure successfully completed.
然后在第一个会话中修改包
CREATE OR REPLACE PACKAGE BODY SimplePkg AS
PROCEDURE UpdateVar IS
vv number;
xx number;
BEGIN
v_GlobalVar1 := 7;
END UpdateVar;
END SimplePkg;
/
第一个会话:
PROD@dev>CREATE OR REPLACE PACKAGE BODY SimplePkg AS
2 PROCEDURE UpdateVar IS
3 vv number;
4 xx number;
5 BEGIN
6 v_GlobalVar1 := 7;
7 END UpdateVar;
8 END SimplePkg;
9 /
Package body created.
PROD@dev>
第二个会话再次调用,报错ORA-06508: PL/SQL: could not find program unit being called: "PROD.SIMPLEPKG"
第二个会话:
PROD@dev>BEGIN
2 simplePkg.UpdateVar;
3 END;
4 /
BEGIN
*
ERROR at line 1:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "PROD.SIMPLEPKG" has been invalidated
ORA-04065: not executed, altered or dropped package body "PROD.SIMPLEPKG"
ORA-06508: PL/SQL: could not find program unit being called: "PROD.SIMPLEPKG"
ORA-06512: at line 2
在一次执行条用,条用正常
PROD@dev>BEGIN
2 simplePkg.UpdateVar;
3 END;
4 /
PL/SQL procedure successfully completed.
PROD@dev>
出现这种情况的原因是因为,对于全局变量,每一个session会生成一个本地copy,如果程序重新编译的话,就会因程序里原变量找不到而丢弃该变量,继而导致这个错误。
也就是说在一个会话中调用程序包package时,会生成package中全局变量的副本,如果在另一个会话中对此package进行编译就会使前一个会话中的副本失效,故而产生错误。
要想避免这个错误,可以使程序捕获ORA-06508:的错误进行处理,也可以重新初始化会话