包的现有状态已被丢弃

Posted

技术标签:

【中文标题】包的现有状态已被丢弃【英文标题】:Existing state of packages has been discarded 【发布时间】:2011-12-16 18:00:27 【问题描述】:

所以我一直在正常运行 PLSQL 程序,并且编译没有错误。我对我的程序进行了一次更改,它仍然可以正常编译,但是现在当我运行它时,我收到了这个错误:

ERROR at line 1:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "SCHEMA.XP_COVER_PAGEP" has been invalidated
ORA-04065: not executed, altered or dropped package body "SCHEMA.XP_COVER_PAGEP"
ORA-06508: PL/SQL: could not find program unit being called: "SCHEMA.XP_COVER_PAGEP"
ORA-06512: at "SCHEMA.XP_ST_002180", line 141
ORA-06512: at line 1

任何想法这可能是什么?我所做的更改是如此微不足道,以至于我怀疑它是否会导致此错误。提前感谢您的帮助!

【问题讨论】:

【参考方案1】:

当会话使用包时,该会话会保留包的某些状态。如果下次相同会话引用该包时重新编译该包,您将收到该错误。

为避免这种情况,请确保断开每个可能已使用包的会话或让会话执行 DBMS_SESSION.RESET_PACKAGE 以重置包状态。

【讨论】:

感谢 darreljnz,该解决方案对我来说效果很好。但一开始我没听懂你在说什么。所以,我只是想为其他人澄清一下你的解决方案。在 pl/sql 中打开一个新的测试窗口并粘贴“Begin sys.dbms_session.reset_package; end;”然后按 F9 执行它,然后对您的包进行更改或重新编译包,现在我们的应用程序中不会出现任何错误 这个问题的最佳答案。很高兴看到这进一步解释了核心问题以及错误发生的原因。 @YogeshJindal 看起来你在说与 darrelinjz 不同的东西。他写道,您需要在包更改后在每个会话上运行 RESET_PACKAGE 以避免错误。 @PauloManuelSantos 我认为他是说要么断开所有会话,要么从会话中运行此命令以重置包状态。 @YogeshJindal 我读到的是每个会话都需要运行这个命令,这在阅读了命令的作用之后是有道理的,RESET_PACKAGE: "这个过程去实例化了这个中的所有包session." 它不应该影响数据库中的其他会话,因此从测试窗口运行它不会影响其他会话。【参考方案2】:

如果你重新编译一个包规范,所有的依赖对象都会失效。 依赖对象是引用重新编译的包规范中的任何声明的任何视图、包规范、包体、函数或过程。

此外,正如 darreljnz 所指出的,会话通常会保留对它们已访问的包状态的引用,从而在下次会话尝试引用包时导致 ORA-04068: existing state of packages has been discarded

后一种行为确实令人讨厌,并且需要编写代码以重试操作或在安装新版本的软件包后关闭所有活动会话(有效地重新启动应用程序/服务)。 底线:安装修补程序变得更加困难。

【讨论】:

【参考方案3】:

在你的包及其正文中使用pragma serially_reusable

【讨论】:

它是做什么的,为什么这是一个解决方案?请详细说明 感谢您的提示,但看起来这会破坏依赖包的触发器。

以上是关于包的现有状态已被丢弃的主要内容,如果未能解决你的问题,请参考以下文章

当我使用异常处理程序时,在第二次尝试后仍然得到 ORA-04068(包的现有状态已被丢弃)

休眠重复查询

有啥方法可以确定包在 Oracle 中是不是有状态?

如何找到Oracle Forms接口集成的PL/SQL程序

滚动列表中的项目时丢弃 SwiftUI 状态

zabbix监控iptables防火墙状态之是否有丢弃的包(攻-击)