在Java/JDBC中透明处理“ORA-04068”错误
在Oracle 里,如果你想编写存储过程你当然应该使用PL/SQL包。在这篇文章里,假设你一般了解PL/SQL 和非常熟悉PL/SQL 包。这篇文章关注于一个令人讨厌的错误,这个错误使许多使用PL/SQL以及使用API(例如JDBC)从应用层调用它的开发人员很苦恼。
【IT专家网独家】
导言
在我们需要与数据库进行交互时,应尽可能地使用存储过程——无论我们使用哪个数据库。这是假设这个数据库提供了编写存储过程的工具,大多数主要的数据库都确实如此,例如Oracle、MySQL和SQL Server。而且无论你是使用Java、.NET或任何其它的编程语言或框架。
在Oracle 里,如果你想编写存储过程你当然应该使用PL/SQL包。在这篇文章里,假设你一般了解PL/SQL 和非常熟悉PL/SQL 包。这篇文章关注于一个令人讨厌的错误,这个错误使许多使用PL/SQL以及使用API(例如JDBC)从应用层调用它的开发人员很苦恼。这个错误就是“ORA-04068: existing state of packages has been discarded”。这个错误是当Oracle认为你的包状态出于某种原因是无效的时候抛出的。在这篇文章里,我们将讨论:
“ORA-04068”错误是什么和它为什么发生,它会影响什么,以及建议的解决方法
下面我们将从定义“ORA-04068”错误开始。
注意: 在这篇文章的示例里使用的是Oracle 9.2.0.3,不过相同的概念在Oracle 10g 中应该也是适用的。
“ORA-04068”错误是什么和它为什么发生?
如果我们使用Oracle的oerr程序看看ORA-04068的定义,我们会得到下面的信息:
| $oerr ora 04068 04068, 00000, "existing state of packages%s%s%s has been discarded" // *Cause: One of errors 4060 - 4067 when attempt to execute a stored procedure. // *Action: Try again after proper re-initialization of any // application's state. |
这个错误显示执行包的现有状态被另一个会话的一个动作无效化了。这个“状态”涉及包在规范或体中定义的任何全局变量(包括常量)。引起这个错误的动作一般是(但不局限于此)在得到了发生错误的会话所使用的连接之后包的重新编译。Oracle 建议的动作是重新初始化应用程序状态以调整包的新状态后重新尝试。
如果我们看些例子就会明白得多。
假设有下面定义的表:
create table t (x number );
有个叫做pkg 的包具有一个叫做p的存储过程,如下所示:
| create or replace package pkg as procedure p; end pkg; / |
下面所显示的包pkg的包体定义了存储过程p只是插入一个常量1到我们先前定义的表t中去。

