【问题标题】:Using Ref Cursor in Oracle SQL Developer在 Oracle SQL Developer 中使用 Ref 游标
【发布时间】:2010-12-11 08:41:11
【问题描述】:

我正在使用 Oracle SQL Developer,但在查看返回 ref 游标的包的结果时遇到问题。下面是包定义:

CREATE OR REPLACE package instance.lswkt_chgoff_recov
as
      type rec_type is record
            (
            source_cd                       lswk_tpr.gltrans.tpr_source_cd%TYPE,
            as_of_dt                        lswk_tpr.gltrans.tpr_as_of_dt%TYPE,
            chrg_off_recov                  varchar2(5),
            process_dt                      lswk_tpr.gltrans.dtgltran%TYPE,
            effect_dt                       lswk_tpr.gltrans.dtgltran%TYPE,
            account_nbr                     lswk_tpr.contract.lcontid%TYPE,
            naics_cd                        lswk_tpr.udfdata.sdata%TYPE,
            prod_type                       varchar2(20),
            off_nbr                         lswk_tpr.schedule.sctrcdty%TYPE,
            borrower_nm                     lswk_tpr.customer.scustnm%TYPE,
            tran_type_cd                    lswk_tpr.gltrans.sglcd%TYPE,
            tran_type_desc                  lswk_tpr.gltrans.sglcd%TYPE,
            tran_amt                        lswk_tpr.gltrans.ctranamt%TYPE,
            note_dt                         lswk_tpr.schedule.dtbk%TYPE,
            accru_cd                        number,
            non_accr_cd                     lswk_tpr.schedule.dtlstincsus%TYPE,
            comm_sb_ind                     varchar2(4)
            );

      type cur_type is ref cursor return rec_type;

      procedure sp
            (
            p_as_of_dt              in      date,
            ref_cur                 in out  cur_type
            );
end;
/

我想这个问题是可能的,如果是这样,我需要做什么。我正在使用 Oracle SQL Developer 1.5.5。谢谢。

韦德

这是我用来调用我的包的代码(由 TOAD 生成):

DECLARE 
  P_AS_OF_DT DATE;
  REF_CUR instance.LSWKT_CHGOFF_RECOV.CUR_TYPE;
  REF_CUR_row REF_CUR%ROWTYPE;

BEGIN 
  P_AS_OF_DT := '31-AUG-2009';

  instance.LSWKT_CHGOFF_RECOV.SP ( P_AS_OF_DT, REF_CUR );

  DBMS_OUTPUT.Put_Line('REF_CUR =');
  IF REF_CUR%ISOPEN THEN
  DBMS_OUTPUT.Put_Line('  SOURCE_CD  AS_OF_DT  CHRG_OFF_RECOV  PROCESS_DT  EFFECT_DT  ACCOUNT_NBR  NAICS_CD  PROD_TYPE  OFF_NBR  BORROWER_NM  TRAN_TYPE_CD  TRAN_TYPE_DESC  TRAN_AMT  NOTE_DT  ACCRU_CD  NON_ACCR_CD  COMM_SB_IND');
    LOOP
      FETCH REF_CUR INTO REF_CUR_row;
      EXIT WHEN REF_CUR%NOTFOUND;
      DBMS_OUTPUT.Put_Line(
           '  ' || '[TPR_SOURCE_CD%type]'
        || '  ' || '[TPR_AS_OF_DT%type]'
        || '  ' || '''' || REF_CUR_row.CHRG_OFF_RECOV || ''''
        || '  ' || '[DTGLTRAN%type]'
        || '  ' || '[DTGLTRAN%type]'
        || '  ' || '[LCONTID%type]'
        || '  ' || '[SDATA%type]'
        || '  ' || '''' || REF_CUR_row.PROD_TYPE || ''''
        || '  ' || '[SCTRCDTY%type]'
        || '  ' || '[SCUSTNM%type]'
        || '  ' || '[SGLCD%type]'
        || '  ' || '[SGLCD%type]'
        || '  ' || '[CTRANAMT%type]'
        || '  ' || '[DTBK%type]'
        || '  ' || NVL(TO_CHAR(REF_CUR_row.ACCRU_CD), 'NULL')
        || '  ' || '[DTLSTINCSUS%type]'
        || '  ' || '''' || REF_CUR_row.COMM_SB_IND || '''');
    END LOOP;
  ELSE
    DBMS_OUTPUT.Put_line('  (Ref Cursor is closed)');
  END IF;


  COMMIT; 
END;

我得到错误:

ORA-06502:PL/SQL:数字或值错误

希望这能更清楚一点。

【问题讨论】:

  • 我看到的只是spc——bdy在哪里?
  • 我遇到的问题是,当我尝试读取 ref 光标时出现错误。我放置 spc 只是为了显示我的 ref cur 的样子,希望有人可以向我展示在 SQL Developer 中运行以输出它的 PL/SQL 代码。
  • @Wade73:与错误相关的行号是多少?对于您提供的内容,我认为这与在 SP 过程中填充 rec_type.accru_cd 相关...
  • 这里是错误:ORA-06502: PL/SQL: numeric or value error ORA-06512: at line 16

标签: sql oracle plsql oracle-sqldeveloper ora-06502


【解决方案1】:

如果您有一个过程需要在 proc 的签名中使用 refcursor,您可以这样做:

var rc refcursor;
execute <package>.my_proc(:rc);
print rc;

突出显示并按 F5。

【讨论】:

    【解决方案2】:

    在你的评论中你说这是错误:

    ORA-06502:PL/SQL:数字或值 错误 ORA-06512:在第 16 行

    无论有时看起来如何,PL/SQL 错误都不是随机生成的。此错误指向有缺陷的数据类型转换,该转换发生在您的过程的第 16 行。如果没有看到您的整个过程,我们就不可能确定第 16 行。幸运的是,SQL Developer 中的代码编辑器会将行号放在装订线中;如果您没有看到行号,则需要切换首选项。

    您需要查找的是将字符串转换为数字或日期变量,或者将数字转换为日期字段。这可能由显式 TO_NUMBER() 或 TO_DATE 发出信号,在这种情况下,您需要检查格式掩码和/或数据内容。或者,您可能有一个隐式演员表。在这种情况下,您可能需要使用适当的格式掩码使其明确。当然,这可能是意外且不需要的转换,因为 SELECT 语句的投影与 REF CURSOR 记录的签名不匹配。这很容易解决。

    【讨论】:

      【解决方案3】:

      您可以在 SQL Developer 中轻松打印 ref_cursor 的输出结果以查看返回值..

      这是一个 Refcursor 函数的示例:

      create or replace function get_employees() return sys_refcursor as
        ret_cursor sys_refcursor;
      begin
        open ret_cursor for
          select * from employees;
        return ret_cursor; 
      end get_employees;
      

      又快又脏的方法:

      select get_employees() from dual; 
      

      整洁的方法:

      variable v_ref_cursor refcursor;
      exec :v_ref_cursor := get_employees(); 
      print :v_ref_cursor
      

      【讨论】:

        【解决方案4】:

        没有看到游标的查询是什么就无法判断。查看您在过程 SP 中运行的 SELECT 语句。您在 rec_type 的数字字段中选择的列之一是返回字符数据,该数据无法转换为数字。

        不要试图弄清楚如何输出游标,而是从 sp 中获取 SELECT 语句并独立运行它。往下看你得到的结果。您将在您期望数字的字段之一中寻找一些非数字值。

        【讨论】:

          【解决方案5】:

          我在生成的程序中看到的唯一显式值是

           P_AS_OF_DT := '31-AUG-2009';
          

          尝试显式转换(改为to_date ('31-AUG-2009', 'DD-MON-YYYY'),也许可以解决问题。

          如果这没有帮助,你能看看你的错误是在 sp 中还是在你的代码中生成的?如果您无法直接解决此问题,请从您拥有的代码中定义一个 sp,设置断点并单步执行代码以查看错误来自何处。

          【讨论】:

            【解决方案6】:

            只需创建一个循环遍历返回的 ref 游标。您可以使用DBMS_OUTPUT.PUT_LINE() 输出到控制台并选择要显示的特定字段。

            【讨论】:

            • 我在上面做了修改,因为那似乎不起作用。
            猜你喜欢
            • 2016-12-19
            • 2018-11-01
            • 1970-01-01
            • 2021-09-11
            • 2011-01-02
            • 2012-08-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多