我有一个使用包(PKG_MY_PACKAGE)的脚本。我将更改该包中查询中的一些字段,然后重新编译它(我不更改或编译任何其他包)。我运行脚本,我收到一个错误,看起来像
ORA-04068: existing state of packages has been discarded ORA-04061: existing state of package body "USER3.PKG_MY_PACKAGE" has been invalidated ORA-04065: not executed,altered or dropped package body "USER3.PKG_MY_PACKAGE" ORA-06508: PL/sql: could not find program unit being called: "USER3.PKG_MY_PACKAGE" ORA-06512: at line 34
我再次运行脚本(不改变系统中的其他任何东西),脚本执行成功。
我以为当我编译之前,我执行的脚本,将修复任何无效的引用。这是100%的可重复性,而且我使用这个脚本越麻烦得到越多。什么可能导致这个,什么会解决它?
(oracle 10g,使用PL / sql Developer 7)
背景
包的现有状态已被丢弃意味着您的包有某种状态。
这是由存储在包体中的全局变量引起的。
直到11.2.0.2,常量也导致这种行为(见documentation)。
由于软件包已经在您的会话中使用,Oracle假定此状态与您相关。这些变量中的一些可能现在具有不同的值,并且当您重新编译Body时,这些值将被重置。
抛出此异常,以便您的客户知道他们不能依赖这些变量。
解决方案
>如果可能,从包体中删除所有全局变量和常量(11gR2之前)
>用DETERMINISTIC函数替换全局变量(如this answer所示)
>使用PRAGMA SERIALLY_REUSABLE
定义软件包会导致Oracle在每次调用服务器时重新初始化全局变量。
>关闭会话并重新连接,然后重新打包。
>手动重置状态(参见Paul James’ answer)