ORA-06508: PL/SQL:无法找到被调用的程序单元

21

我正在使用Oracle 10g和Toad 11.5。我正在尝试从匿名块中调用API。

如果我在添加了dbms_output.put_line之后重新编译API,然后尝试执行匿名块,它会显示错误:

"ORA-06508: PL/SQL: could not find program unit being called".

然而,如果我结束当前会话并打开新的会话,那么匿名块将在没有错误的情况下执行。

由于这个问题,每次对API进行更改时,我都不得不重新连接会话。有人可以帮忙解决这个问题吗?是否可以通过在toad或数据库级别进行任何配置来解决此问题。


2
你是否也遇到了类似“现有包状态已被丢弃”的情况?如果是这样,在同一会话中第二次运行它应该可以解决问题。但这可能意味着你的包有一些状态,即在包中声明的变量而不是在过程中声明(与dbms_output无关)。 - Alex Poole
4个回答

23

我怀疑你只是在报告类似这样的堆栈中的最后一个错误:

ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "schema.package" has been invalidated
ORA-04065: not executed, altered or dropped package body "schema.package"
ORA-06508: PL/SQL: could not find program unit being called: "schema.package"
如果出现这种情况,那是因为您的包是有状态的:(参考文档)
声明在包规范或主体中的变量、常量和游标的值构成其包状态。如果一个PL/SQL包至少声明了一个变量、常量或游标,则该包是有状态的;否则,它是无状态的。
当重新编译时状态会丢失:
如果已实例化的有状态包的主体被重新编译(显式地使用“ALTER PACKAGE语句”或隐式地),包中的下一次子程序调用会导致Oracle数据库放弃现有的包状态并引发异常ORA-04068。
在PL/SQL引发异常后,对包的引用会导致Oracle数据库重新实例化该包,从而重新初始化它...。
如果您的包具有状态,则无法避免这种情况。不过我认为需要包是有状态的情况非常罕见,因此您应该重新审查在函数或过程之外声明的任何内容,以查看是否真的需要在该级别上使用它们。由于您使用的是10g版本,因此这也包括常量,而不仅仅是变量和游标。
但引用所引用的文档的最后一段意味着,在同一会话中下次引用包时,您将不会收到错误并且它将正常工作(直到再次重新编译)。

完全同意你的看法。我对此毫不在意。只要运行该进程。我已经尝试从调用匿名块中排除它,但必须在该魔术标志清除之前完全运行。真是令人恼火! - Pecos Bill
非常好的解释。我遇到过很多情况,其中包是有效的,已经明确编译,尝试了多次调用,但仍然出现此错误。由于某种原因,在它看到有效的包之前,需要断开并重新连接连接。在单个调用尝试中优雅地处理此场景,而不生成错误,对于发生在大型企业环境中的任何部署都会产生极其负面的影响。 - AaronLS

7

4

根据之前的回答,我通过将包级别的全局变量转移到过程中解决了我的问题,因为在我的情况下没有任何影响。

原始脚本如下:

create or replace PACKAGE BODY APPLICATION_VALIDATION AS 

V_ERROR_NAME varchar2(200) := '';

PROCEDURE  APP_ERROR_X47_VALIDATION (   PROCESS_ID IN VARCHAR2 ) AS BEGIN
     ------ rules for validation... END APP_ERROR_X47_VALIDATION ;

/* Some more code
*/

END APPLICATION_VALIDATION; /

将不带全局变量 V_ERROR_NAME 的相同代码重写,并移动到包级别下的过程中:

修改后的代码

create or replace PACKAGE BODY APPLICATION_VALIDATION AS

PROCEDURE  APP_ERROR_X47_VALIDATION (   PROCESS_ID IN VARCHAR2 ) AS

**V_ERROR_NAME varchar2(200) := '';** 

BEGIN
     ------ rules for validation... END APP_ERROR_X47_VALIDATION ;

/* Some more code
*/

END APPLICATION_VALIDATION; /

4

尽管只有包体发生了变化,我还是重新编译了包规范。这解决了我的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接