PL / SQL失效

时间:2014-05-12 05:39:33

标签: oracle plsql

我有一个JDBC会话引用PL / SQL包的场景。当我更改包体并重新编译它时,会话不会抛出任何异常,但是当我重新编译包规范时,它会抛出以下异常。我的问题是为什么当包体改变时会话不会抛出任何异常,如果我在包体中进行了更改,现有会话是否会看到更改?

ORA-04068: existing state of packages has been discarded

3 个答案:

答案 0 :(得分:0)

如果PL / SQL包具有全局变量(常量或可修改),则认为包具有状态。如果更改包,则会重新初始化变量并丢失状态。

如果数据库会话已使用该程序包,则下次访问程序包时将收到ORA-04068异常。如果它处理异常,则可以继续使用该包而不会再次收到异常。当然,国家已经失败,新版本的套餐也适用。

对于没有全局变量的PL / SQL包,不会抛出任何错误。新版本的软件包立即适用于所有会话。

那么,如果在该会话中不再使用更改的包,为什么会期望会话抛出异常?这会带来更多问题,而不是增值。

答案 1 :(得分:0)

阅读" 更轻松的应用程序设计"和" 隐藏的实施细节"在Reasons to use Packages

最重要的是" 包装编写指南" (同一页)明确说明:

  

在包规范中,仅声明必须可见的项目   调用程序。

     

这种做法可以防止其他开发人员构建不安全的问题   依赖于您的实现细节并减少对您的需求   重新编译。

     

如果更改包规范,则必须重新编译   调用包的公共子程序的子程序。如果你   只更改包体,您无需重新编译   子程序。

答案 2 :(得分:0)

这是一个众所周知的问题。 在这里,您可以找到有关如何解决它的任何细节。 http://laurentschneider.com/wordpress/2010/12/how-to-solve-ora-4068.html

但是如果你对全局变量要非常小心!如果它们在您的包中使用,那么在其他程序使用它时不要编译您的包。

从dba的角度来看,通过v $ access视图可以知道谁在这个包上有“锁定”。所以你可以通过ddl上的触发器来引发编译。