我正在使用oracle 10g和toad 11.5。我试图从匿名块中调用api。
如果我在添加dbms_output.put_line
后重新编译api然后尝试执行匿名块,则会显示错误
"ORA-06508: PL/SQL: could not find program unit being called".
但是,如果我结束当前会话并打开一个新会话,那么匿名块将执行而不会出错。
由于这个问题,每次我对API进行更改时都会重新连接会话。 如果可以通过在toad或数据库级别进行任何配置来解决此问题,任何人都可以提供帮助。
答案 0 :(得分:22)
我怀疑你只报告堆栈中的最后一个错误:
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"
如果是这样,那是因为your package is stateful:
包的变量,常量和游标的值 声明(在其规范或正文中)包含其包 状态即可。如果PL / SQL包声明至少一个变量,常量, 或光标,然后包有状态;否则,它是无状态。
重新编译时状态丢失:
如果重新编译实例化的有状态包的主体(或者 显式地,使用“ALTER PACKAGE语句”,或隐含地), 下一次调用包中的子程序会导致Oracle数据库 丢弃现有的包状态并引发异常 ORA-04068。
PL / SQL引发异常后,对包的引用会导致 Oracle数据库重新实例化包,重新初始化 它...
如果你的包有状态,你无法避免这种情况。我认为真的需要一个包有状态是非常罕见的,所以你应该重新审视你在包中声明的任何东西,但是在函数或过程之外,看看它是否真的需要在那个级别。因为你在10g上,它包括常量,而不仅仅是变量和游标。
但引用文档中的最后一段意味着下次在同一会话中引用包时,您将不会收到错误,它将正常工作(直到您再次重新编译)。
答案 1 :(得分:5)
答案 2 :(得分: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; /
答案 3 :(得分:0)
我重新编译了软件包规范,即使更改只是在软件包主体中。这解决了我的问题