PL/SQL包无效

Fru*_*ner 24 oracle plsql

我有一个使用包的脚本(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)

Pau*_*ulJ 22

如果你在脚本中运行东西,请在运行重新编译的代码之前在那里尝试这些命令.

exec DBMS_SESSION.RESET_PACKAGE
exec DBMS_SESSION.MODIFY_PACKAGE_STATE( DBMS_SESSION.REINITIALIZE )
Run Code Online (Sandbox Code Playgroud)

他们按照名字的意思行事.


Pet*_*ang 21

背景

existing state of packages has been discarded 意味着,您的包具有某种状态.

这是由存储在Package Body中的全局变量引起的.
在11.2.0.2之前,常量也会导致此行为(请参阅文档).

由于程序包已在会话中使用,因此Oracle假定此状态与您相关.其中一些变量现在可能具有不同的值,当您重新编译Body时,将重置这些值.

抛出此异常,以便您的客户知道他们不能再依赖这些变量了.

解决方案

  • 如果可能,从Package Body中删除所有全局变量和常量(11gR2之前)
  • DETERMINISTIC函数替换全局变量(如本答案所示)
  • 定义包PRAGMA SERIALLY_REUSABLE会导致Oracle在每次调用服务器时重新初始化全局变量.
  • 关闭会话并重新连接,然后再次调用该程序包.
  • 手动重置状态(参见Paul James的回答)