2012-03-17 40 views
1

ODP.Net方法调用打包的存储过程,每次调用时都会重新创建表。 在随后的每次通话中抛出错误每次后续调用都无效的Oracle软件包

ORA-04061: existing state of package body "SAAP.PRICEWORX" has been invalidated 
ORA-06508: PL/SQL: could not find program unit being called: "SAAP.PRICEWORX" 

我该怎么做这件事?

+0

从http://ora-04061.ora-code.com/,你只需要调用它两次,它应该第二次工作 – 2012-03-17 12:55:45

回答

4

我的猜测是你的软件包会丢弃或引用你正在创建的表。所以,在某些时候,软件包可能试图引用一个不存在的表。

事件的顺序可能会是这样的:

  1. 表存在
  2. 使用表
  3. DROP TABLE
  4. 再次尝试使用表 - 包是无效的,因为表不再存在。
  5. 创建表 - 一切都很好。

简单的答案不是在代码中创建或删除表。改为创建一个global temporary table。这使桌子永远在那里。

最糟糕的选择是将每个使用该表的可能或不可能存在于execute immediate中的单个呼叫包装在一起。

如果我完全错了,那么你需要调查你的软件包为什么无效并发布结果。它无效的事实并不意味着太多。

+0

Upvoted,谢谢你的信息答案。通过执行dbms_session.modify_package_state(dbms_session.reinitialize)找到快捷方式解决方案;在proc.http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_sessio.htm#BHCEIDAB – TonyP 2012-03-17 14:23:35

+0

@TonyP开始,我很高兴有所帮助,不得不承认我有一个出于同样的原因,在我的数据库中使用'alter package compile';只是没有时间来解决问题。如果你可以避免这样做,这是值得的。 – Ben 2012-03-17 21:44:50

2

删除任何对象会导致引用它的所有对象被标记为无效。引用此无效对象的对象也可以标记为无效,等等。所以,看起来你的软件包引用了这个表,或者取决于某些事情。

我不得不承认,我理解Oracle为什么会抛出一个ORA-04061错误,并且在您第一次调用无效包时不会自动重新验证包。但是,我不认为这是一个问题。在应用程序运行时,您不应该真正创建或删除表。你为什么需要这样做?

如果您正在寻找比DELETE FROM my_table更快的清空表格的方法,请使用TRUNCATE TABLE my_table。请注意,TRUNCATE是DDL,如CREATE,ALTERDROP,因此您需要将呼叫打包到EXECUTE IMMEDIATE

相关问题