【问题标题】:ORA-06508: PL/SQL: could not find program unit being calledORA-06508: PL/SQL: 找不到被调用的程序单元
【发布时间】:2013-10-22 23:24:12
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 您是否也收到类似“现有包状态已被丢弃”的信息?如果是这样,在同一会话中第二次运行它应该可以工作。但这表明您的包具有某种状态,即在包中而不是在过程中声明的变量(与dbms_output 无关)。

标签: oracle plsql anonymous


【解决方案1】:

我重新编译了包规范,尽管更改只是在包体中。这解决了我的问题

【讨论】:

    【解决方案2】:

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

    原来的脚本

    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】:

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

      请参阅this 答案。

      这是一个awesome explanation about this error

      【讨论】:

        【解决方案4】:

        我怀疑您只是在报告堆栈中的最后一个错误,如下所示:

        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,这包括常量,而不仅仅是变量和游标。

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

        【讨论】:

        • 完全同意你的看法。我可以关心这个虚数。只需运行该死的过程。我已经尝试将它从调用匿名块中排除,并且它绝对必须在该魔术标志清除之前运行完成。烦人!
        • 很好的解释。我遇到过很多包有效、显式编译、多次尝试调用但仍然出现此错误的情况。由于某种原因,需要断开连接并重新连接,然后才能看到有效的包。这种情况可以在一次调用尝试中优雅地处理,而不会产生错误。对大型企业环境中发生的任何部署都会产生难以置信的负面影响
        猜你喜欢
        • 2013-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        • 2013-12-27
        • 1970-01-01
        相关资源
        最近更新 更多