在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专家网    作者:戴羽    责编:豆豆技术应用

正在加载评论...