PL / SQL包失效

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


背景

existing state of packages has been discarded意味着你的包有某种状态。

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

由于该包已在您的会话中使用过,因此Oracle假定此状态与您相关。 其中一些变量现在可能有不同的值,并且当您重新编译正文时,值将被重置。

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

解决方案

  • 如果可能,从Package Body中移除所有全局变量和常量(在11gR2之前)
  • DETERMINISTIC函数替换全局变量(正如本答案所建议的那样)
  • 使用PRAGMA SERIALLY_REUSABLE定义包会导致Oracle在每次调用服务器时重新初始化全局变量。
  • 再次调用软件包之前关闭会话并重新连接。
  • 手动重置状态(请参阅Paul James的回答)

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

    exec DBMS_SESSION.RESET_PACKAGE
    exec DBMS_SESSION.MODIFY_PACKAGE_STATE( DBMS_SESSION.REINITIALIZE )
    

    他们按照名字的意思去做。


    您可能遇到的问题是:

  • 你调用的程序包/程序是无效的(尽管它可以独立调用它可以工作)在这个all_objects视图中检查这个查询是否有你的程序包或对象中使用的对象条目

    select * from all_objects where status ='INVALID'and owner ='SCHEMA_NAME';

  • 检查你的包是否有全局变量? 如果是,那么检查这些变量是否未被任何其他会话更改,最好删除这些全局变量/使用函数

  • 在脚本下运行以编译模式中的所有对象

    开始dbms_utility.compile_schema('SCHEMA_NAME',false); 结束;

  • 最后一个选项,如果没有上述工作,然后从你的包中删除所有的程序/功能,添加新的功能,并尝试从触发器运行你的功能。 检查是否有效,然后你的包裹处于特殊锁定状态。 在添加一个新的函数/ proc之后,它的状态将会再次生效,然后你可以添加所有的实际funcs / procs并删除新添加的函数/ proc。
  • 链接地址: http://www.djcxy.com/p/36923.html

    上一篇: PL/SQL Package invalidated

    下一篇: Oracle ORA