在Java/JDBC中透明处理“ORA-04068”错误
http://tech.ddvip.com 2008年05月08日 社区交流
内容摘要:在Oracle 里,如果你想编写存储过程你当然应该使用PL/SQL包。在这篇文章里,假设你一般了解PL/SQL 和非常熟悉PL/SQL 包。这篇文章关注于一个令人讨厌的错误,这个错误使许多使用PL/SQL以及使用API(例如JDBC)从应用层调用它的开发人员很苦恼。
现在我们在会话1中执行存储过程p。
session1>execpkg.p
PL/SQLproceduresuccessfullycompleted.
开启一个新的会话“session 2”并通过重新创建这个包来重新编译它。
session2>@pkg_body
session2>createorreplacepackagebodypkgas
2g_constantconstantnumber:=1;
3procedurep
4is
5begin
6insertintot(x)values(1);
7endp;
8endpkg;
9/
Packagebodycreated.
session2>showerrors;
再次在会话1中执行存储过程p,得到下面的结果:
session1>execpkg.p
BEGINpkg.p;END;
*
ERRORatline1:
ORA-04068:existingstateofpackageshasbeendiscarded
ORA-04061:existingstateofpackagebody"ORA92.PKG"hasbeeninvalidated
ORA-04065:notexecuted,alteredordroppedpackagebody"ORA92.PKG"
ORA-06508:PL/SQL:couldnotfindprogramunitbeingcalled
ORA-06512:atline1
发生了什么?当我们重新在会话2中编译包体时,我们重置了包的状态。换句话说,对于任何在包编译之前连接的会话,包的执行状态(在这种情况下,由在包体里指定给常量的值来定义)被从内存中删除了。注意,我们实际上没有改变这个状态(我们在重新编译的时候保持相同的常量值),但是Oracle没有跟踪这一级别上的细节。只要连接了Oracle,在会话2里,重新编译了包pkg——这个包的状态现在重置为一个新的状态——所以对于任何在这个重新编译发生之前已经连接到Oracle的已有会话来说,包的状态变为无效。因此任何存储过程或包的函数下一次执行时,就会立即抛出ORA-04068错误。
来源:IT专家网 作者:戴羽 责编:豆豆技术应用