19

我正在使用 oracle 10g 和 toad 11.5。我正在尝试从匿名块调用 api。

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

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

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

由于这个问题,每次我对 API 进行更改时,我都会重新连接会话。如果可以通过在 toad 或数据库级别进行任何配置来解决此问题,任何人都可以提供帮助。

4

4 回答 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,因此其中包括常量,而不仅仅是变量和游标。

但是引用文档的最后一段意味着下次您在同一会话中引用该包时,您将不会收到错误并且它将正常工作(直到您再次重新编译)。

于 2013-10-15T12:03:56.507 回答
6

似乎打开一个新会话是关键。

看到这个答案。

这是关于这个错误的一个很棒的解释

于 2014-09-22T08:16:50.633 回答
3

根据之前的答案。我通过在程序包级别删除全局变量来解决我的问题,因为对我的情况没有影响。

原始脚本

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; /
于 2015-10-15T14:07:32.193 回答
2

我重新编译了包规范,即使更改仅在包体中。这解决了我的问题

于 2019-07-04T14:15:01.033 回答