哪些情况会导致 Oracle 包失效?
Posted
技术标签:
【中文标题】哪些情况会导致 Oracle 包失效?【英文标题】:What Situations Cause Oracle Packages to Become Invalid? 【发布时间】:2010-10-12 04:39:30 【问题描述】:产生这个问题的场景:
我们有一个包是另一个包的依赖项,有时对“父”包进行更改会导致依赖包无效,但有时不会。
它曾经让我们感到意外。
简单地了解导致失效的原因会非常有用,这样我就可以预测/计划它。
【问题讨论】:
哪个版本?它实际上因版本而异。 这是 Oracle 应用程序版本,afaik。没有具有该标识符的 RDBMS。 select * from v$version 会告诉你。 【参考方案1】:更改包所依赖的任何对象(例如表、视图、触发器、其他包)都会自动将包标记为无效。正如上面的 tuinstoel 所说,Oracle 足够聪明,可以在第一次使用时重新编译包。
如果您对此感到担忧,每次进行架构更改(例如表、视图、触发器、过程)时,请运行DBMS_UTILITY.compile_schema
(或让您的 DBA 执行此操作)。这将强制编译所有包,并在您发现错误之前让您知道哪里有错误,或者是否有错误。
【讨论】:
警告:DBMS_UTILITY.COMPILE_SCHEMA() 从Oracle8i 开始不推荐使用,从9i 开始绝对不推荐使用。我们可以摆脱它,但这里有更可靠的选择。请参阅我对其他线程的回答 ***.com/questions/3200202/…【参考方案2】:或者你可以查询下表看看你有哪些依赖
select *
from dba_dependencies
where name = 'YOUR_PACKAGE'
and referenced_owner = 'ANYUSER' --- Comment this out if you are looking for yourself
and owner = USER --- Or can be set to any user
这将显示所有依赖项。对于您的对象查询 user_dependencies。
【讨论】:
【参考方案3】:我同意 Thomas Jones-Low 的观点,但是长会话和重新编译还有几个问题。
如果您在会话中引用了一个包,并且该包(或依赖包)在同一会话期间被重新编译,那么您将收到 oracle 错误“ORA-06508: PL/SQL: 找不到被调用的程序单元”
一旦您在会话中引用了包,您通常无法更改包而不使该包在该会话中失效。这对于包经常更改的开发环境来说是一个特殊的问题,但对于想要在不关闭整个环境的情况下做一个小补丁的生产环境来说也是一个问题。请注意,即使更改的包中没有错误,也会发生此错误。
【讨论】:
【参考方案4】:顺便说一句,如果我完全错了……提前道歉
感到意外?
不知道这意味着什么......
生产中有什么问题吗?
到底发生了什么?
我之所以这么问,是因为理解每一个可能的变化的后果比处理结果要困难得多。为什么失效会成为一个问题?我的猜测是因为您的应用程序中出现“包的现有状态已被丢弃”错误。这是真正的问题吗?
我再次怀疑是这样,如果是这样,让我们处理它而不是我在评论中添加的更改列表是特定于版本的。 (例如,11g 将依赖关系跟踪到表的列而不是整个表)。
如果你没有使用包状态,这对你来说可能不是一个重要的错误。如果你是,这将是一个重要的错误,你不会感到惊讶,所以我猜你不会。
因为你不是这个错误可以忽略。由于您可以安全地忽略它,您可以编写客户端应用程序以忽略此错误并重试您的调用,因为正如其他人指出的那样,Oracle 将为您重新编译您的包。这是一个很有价值的练习。因为当您进行更改时,您不必知道您需要担心的所有可能的事情,然后在紧急修复中您忘记其中的一件,您的应用会处理它并继续前进,而无需担心。
【讨论】:
很遗憾没有编译指示或“我不关心包状态更改”的东西 有一个 pragmaSERIALLY_REUSABLE
可以满足要求,但方式略有不同,每次调用都会重新初始化包状态。【参考方案5】:
除了 Thomas Jones-Low 的回答之外,如果您只修改包 BODY,则依赖对象可能不会被标记为无效。
但是,一旦您修改了包规范,这必然会发生。
【讨论】:
【参考方案6】:如果尝试执行一个无效的 Oracle 包,Oracle 将尝试编译它。只有在编译Oracle后仍然无效时才会抛出异常。
【讨论】:
以上是关于哪些情况会导致 Oracle 包失效?的主要内容,如果未能解决你的问题,请参考以下文章