【问题标题】:Successfully compiled Oracle package fails when called with 'ORA-04063: package body "..." has errors使用 'ORA-04063: package body "..." 调用成功编译的 Oracle 包失败
【发布时间】:2013-06-24 21:52:53
【问题描述】:

我有一个 pkg 用于保存面向报告的代码 CMS_REPORTS。

我添加了一个返回 ref 游标的过程,并且 pkg 编译得很好,但是当我调用 proc 来测试它时失败: ORA-04063: 包体 "CMS.CMS_REPORTS" 有错误 ORA-06508: PL/SQL: 找不到被调用的程序单元: "CMS.CMS_REPORTS"

我已经删除了 orig proc 并用它替换它以保持简单 - 同样的问题。

过程是这样的:

procedure test_ref_cur(p_testno    in  number,
                       p_cur       in out ref_cur) as 
begin 

  open p_cur for
    select p_testno + 1 from dual;

end test_ref_cur;

我在 pkg 规范中定义了 ref 光标,如下所示:

 type ref_cur is ref cursor;
  procedure test_ref_cur(p_testno    in  number,
                         p_cur       in out ref_cur);

我尝试了各种使用 ref cursor 和 sys_refcursor 的组合,但都出现了相同的错误。如果我从 pkg 中删除 proc,它可以正常工作。

我开始认为这是系统问题?

有其他人遇到过这个问题吗?

问候 戴夫

【问题讨论】:

  • 你怎么知道包编译了?我见过工具设置,一切看起来都不错,但包实际上并没有被编译,所以只有在显式编译或启动时才会出现问题。
  • show errors 为您提供了什么,或者如果您的客户不支持,select * from user_errors where type like 'PACKAGE%' and name = 'CMS_REPORTS'?你所展示的对我来说编译和运行都很好,所以图片中缺少一些东西。

标签: oracle compilation compiler-errors package


【解决方案1】:

很难说这里有什么问题,因为看起来我们没有看到相关代码。

因此,我建议您仔细检查以下几点:

  • 包和包体都在那里,实际编译无异常

  • 您位于包含包和包主体的架构/用户中。

  • 没有其他同名对象可能会隐藏您的包/包主体

  • 您尝试调用的过程存在于包包体中。

  • 从包 + 包主体中删除所有代码,除了一个简单的过程,并检查它是否有效。

如果您已完成所有这些,请使用结果更新问题。

【讨论】:

    【解决方案2】:

    为了实现你想要的,你必须使用 SYS_REFCURSOR:

    create procedure test_ref_cur(p_testno    in  number,
                           p_cur       in out SYS_REFCURSOR) as 
    begin 
    
      open p_cur for
        select p_testno + 1 from dual;
    
    end test_ref_cur;
    -- PROCEDURE TEST_REF_CUR compiled
    

    ...和示例:

    DECLARE
        l_sysrc SYS_REFCURSOR;
        l_num   NUMBER;
    
        procedure test_ref_cur(p_testno    in  number,
                               p_cur       in out SYS_REFCURSOR) as 
        begin 
    
          open p_cur for
            select p_testno + 1 from dual;
    
        end test_ref_cur;
    BEGIN
        test_ref_cur(1, l_sysrc);
    
        FETCH l_sysrc INTO l_num;
    
        DBMS_OUTPUT.PUT_LINE(l_num);
    END;
    -- Result:
    -- 2
    

    自 Oracle 7.3 起,REF CURSOR 类型可用于允许 要从存储过程和函数返回的记录集。甲骨文 9i 引入了预定义的 SYS_REFCURSOR 类型,这意味着我们不再 必须定义我们自己的 REF CURSOR 类型。

    来源:http://www.oracle-base.com/articles/misc/using-ref-cursors-to-return-recordsets.php

    【讨论】:

    • OP 用他自己的ref cursor 做的事情应该(并且确实)仍然有效;问题是他在sys_refcursor 上遇到了同样的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多