11

创建此问题的场景:

我们有一个包是另一个包的依赖项,有时对“父”包进行更改会导致依赖包无效,但有时不会。

它以前曾让我们感到意外。

简单地了解导致失效的原因将非常有用,这样我就可以预测/计划它。

4

6 回答 6

15

更改包所依赖的任何对象(例如表、视图、触发器、其他包)都会自动将包标记为无效。正如上面 tuinstoel 所指出的,Oracle 足够聪明,可以在第一次使用包时重新编译它。

如果您对此感到担忧,那么每次您进行模式更改(例如表、视图、触发器、过程)时,运行一个DBMS_UTILITY.compile_schema (或让您的 DBA 执行)。这将强制编译所有包,并在您发现错误之前让您知道哪里有错误,或者是否有错误。

于 2009-03-09T14:46:01.923 回答
6

或者您可以查询下表查看您有哪些依赖项

   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。

于 2009-07-08T07:12:39.157 回答
4

我同意 Thomas Jones-Low 的观点,但是还有一些与长时间会话和重新编译有关的问题。

如果您在会话中引用一个包并且该包(或依赖包)在同一会话期间重新编译,那么您将收到 oracle 错误“ORA-06508:PL/SQL:找不到被调用的程序单元”

一旦您在会话中引用了包,您通常无法更改包而不使该包无效。对于包经常更改的开发环境来说,这是一个特殊的问题,但对于想要在不关闭整个环境的情况下做一个小补丁的生产环境来说也是一个问题。请注意,即使更改的包中没有错误,也会发生此错误。

于 2009-03-09T20:29:06.980 回答
3

顺便说一句,如果我对这种情况完全错了......提前道歉

被吓到了?

不知道这意味着什么...

生产中有什么问题吗?

究竟发生了什么?

我问的原因是因为理解每一个可能的变化的后果比处理结果要困难得多。为什么失效会成为一个问题?我的猜测是因为您的应用程序中出现“包的现有状态已被丢弃”错误。这是真正的问题吗?

我再次怀疑它是,如果是这样,让我们​​处理它而不是我在评论中放置的更改列表是特定于版本的。(例如,11g 将依赖关系跟踪到表的列而不是整个表)。

如果您不使用包状态,这对您来说可能不是一个重要的错误。如果你是这将是一个重要的错误,你不会感到惊讶,所以我猜你不是。

既然你不是这个错误可以忽略。由于您可以安全地忽略它,您可以编写客户端应用程序以忽略此错误并重试您的调用,因为正如其他人指出的那样,Oracle 将为您重新编译您的包。这是一个很有价值的练习。因为当您进行更改时,您不必知道您需要担心的所有可能的事情,然后在紧急修复中您忘记其中的一件,您的应用程序只会处理它并继续前进,而无需担心。

于 2009-03-09T15:20:26.083 回答
2

除了 Thomas Jones-Low 的回答之外,如果您只修改包 BODY,则依赖对象可能不会被标记为无效。

但是,一旦您修改了包规范,这必然会发生。

于 2009-03-09T14:50:12.193 回答
1

如果尝试执行一个无效的 Oracle 包,Oracle 将尝试编译它。只有在编译Oracle后仍然无效时才会抛出异常。

于 2009-03-09T14:28:19.983 回答