PL / SQL包无效

时间:2010-03-23 18:48:11

标签: 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)

4 个答案:

答案 0 :(得分:21)

<强>背景

existing state of packages has been discarded表示您的包具有某种状态。

这是由存储在Package Body中的全局变量引起的 在11.2.0.2之前,常量也会导致这种行为(见documentation)。

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

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

<强>解决方案

  • 如果可能,从包体中删除所有全局变量和常量(11gR2之前)
  • DETERMINISTIC函数替换全局变量(由this answer建议)
  • 使用PRAGMA SERIALLY_REUSABLE定义软件包会导致Oracle在每次调用服务器时重新初始化全局变量。
  • 关闭您的会话并重新连接,然后再次调用该包。
  • 手动重置状态(请参阅Paul James' answer

答案 1 :(得分:21)

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

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

他们按照名称的意思行事。

答案 2 :(得分:1)

以上错误:ORA-06508:PL / SQL:找不到被调用的程序单元。

尝试调用无法找到的存储程序时会导致

。该程序可能已被删除或不兼容修改,或已编译错误。

检查所有引用的程序,包括其包体,是否存在且兼容。

您可以运行此查询以查找可能导致ORA-06508错误的无效对象:

选择    comp_id,    COMP_NAME,    版,    状态,    命名空间,    模式 从    dba_registry;

答案 3 :(得分:0)

您可能遇到的问题是:

  • 您调用的包/过程无效(尽管如果单独调用它可以工作) 在此 all_objects 视图中检查此查询是否包含您的包或包中使用的对象的条目

    从all_objects中选择*,其中status =&#39; INVALID&#39;和所有者=&#39; SCHEMA_NAME&#39;;

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

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

    开始    dbms_utility.compile_schema(&#39; SCHEMA_NAME&#39;,FALSE);    端;

  • 最后一个选项如果以上都不起作用,则从包中删除所有过程/函数,添加新函数并尝试从触发器运行您的函数。检查这是否有效然后你的包是特殊锁。添加新函数/ proc后,它的状态将再次有效,然后您可以添加所有实际的funcs / procs并删除新添加的函数/ proc。