【问题标题】:Frequent error in Oracle ORA-04068: existing state of packages has been discardedOracle ORA-04068 中的常见错误:包的现有状态已被丢弃
【发布时间】:2017-09-22 21:21:02
【问题描述】:

我们每天在每两小时运行一次的脚本上遇到此错误,但在一天中的不同时间。

ERROR at line 1:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "PACKAGE.NAME" has been
invalidated
ORA-06508: PL/SQL: could not find program unit being called:
"PACKAGE.NAME"
ORA-06512: at line 1

谁能列出哪些情况会导致此错误,以便我们进行调查?

谢谢。

更新: 执行'ALTER SESSION CLOSE DATABASE LINK DBLINK' 会使包的状态无效吗?

【问题讨论】:

  • 作为进一步的信息,编译包主体不会使调用包“变为无效” - 即数据字典仍将显示所有包和触发器以及任何“有效”。失效的是每个用户的 PGA。因此,如果有 10 个用户在重新编译包时使用该包,那么每个用户在下次引用该包时都会依次遇到这个问题。

标签: sql oracle oracle10g


【解决方案1】:

这一班轮实际上解决了一切:

PRAGMA SERIALLY_REUSABLE;

确保您的全局变量是无状态的以避免任何问题。

【讨论】:

  • 更准确地说,这个 pragma 会在每次向数据库请求时重置包状态(再次执行包初始化)。
  • 此编译指示无法解决“所有问题”。它仅适用于特定用例。
【解决方案2】:

包有公共或私有变量。 (对吗?)这个变量构成了包的状态。如果您在第 3 次会话中编译包。下一次访问这个包会抛出 ORA-04068。

包的构建时间戳必须早于包会话状态。

如果脚本运行不需要包状态,请在脚本开头调用DBMS_SESSION.RESET_PACKAGE。这会清除会话的所有包状态。

【讨论】:

  • 将尝试指定的调用。谢谢。
  • 一个问题,如何在第 3 次会话中编译包使其无效?
  • martilyo:新版本的包可能有更多/更少/其他包变量。事实上,如果你编译一个完全没有包变量的包,那些 ORA-04068 错误就不会发生。在繁忙的工作时间内,夜魔侠会在生产系统上这样做..
  • 执行“ALTER SESSION CLOSE DATABASE LINK DBLINK”会使包的状态无效吗?
【解决方案3】:

您也可以查看dba_dependenciesuser_dependencies

select *
from dba_dependencies
where name = 'YOUR_PACKAGE'
and type = 'PACKAGE' --- or 'PACKAGE_BODY'
and owner = USER --- or USERNAME

这将为您提供您的包所依赖的对象。检查那里发生了什么。

【讨论】:

    【解决方案4】:

    这个问题我们已经有好几次了,暂时我们正在编译架构来临时解决这个问题。几天来,我们一直在寻找永久解决方案。

    我们发现下面的查询显示了我们的同义词中的时间戳差异。我们重新编译了同义词,它起作用了!!!已经快一周了,到目前为止我们没有任何问题。这是对我们的案例有帮助的查询。

    **

    select do.obj# d_obj,do.name d_name, do.type# d_type, po.obj# p_obj,po.name p_name,
    to_char(p_timestamp,'DD-MON-YYYY HH24:MI:SS') "P_Timestamp",
    to_char(po.stime ,'DD-MON-YYYY HH24:MI:SS') "STIME", 
    decode(sign(po.stime-p_timestamp),0,'SAME','*DIFFER*') X 
    from sys.obj$ do, sys.dependency$ d, sys.obj$ po
    where P_OBJ#=po.obj#(+) and D_OBJ#=do.obj# 
    and do.status=1 /*dependent is valid*/ 
    and po.status=1 /*parent is valid*/ 
    and po.stime!=p_timestamp /*parent timestamp not match*/ 
    order by 2,1;
    

    **

    我希望这对可能遇到此问题的人有所帮助。

    【讨论】:

      【解决方案5】:

      您似乎正在对您的对象进行更改,从而使其他对象无效。例如,删除索引可以使依赖于该表的所有包都处于无效状态。它可以产生级联效应。如果包无效,依赖于包的函数和使用该函数的视图可能会失效。尝试在每次 DDL 查询后重新编译所有对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-12
        • 2014-12-26
        • 1970-01-01
        • 1970-01-01
        • 2015-08-22
        • 2017-06-18
        • 2018-11-22
        相关资源
        最近更新 更多