在Oracle SQL Developer中使用参考游标

问题描述:

我正在使用Oracle SQL Developer,但是我看到返回参考游标的包的结果有问题。下面是封装的定义:在Oracle SQL Developer中使用参考游标

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:数字或值错误

希望这会使它更清晰一点。

+0

我看到的全部是spc - 哪里是bdy? – 2009-10-29 18:16:25

+0

你有什么“问题”? – kurosch 2009-10-29 18:27:03

+0

我遇到的问题是,当我尝试阅读参考游标时,我得到错误。为了显示我的参考看起来像什么,并且希望有人能够向我展示要在SQL Developer中运行的PL/SQL代码以输出它,我放置了spc。 – Wade73 2009-10-29 19:21:51

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

这里有一个指针函数的例子:

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 

只需制作一个循环,该循环遍历返回的参考光标。您可以使用DBMS_OUTPUT.PUT_LINE()并选择要显示的特定字段输出到控制台。

+0

我上面做了一个修改,因为这似乎没有工作。 – Wade73 2009-10-29 20:11:31

我在生成的程序看到的唯一明确的值是

P_AS_OF_DT := '31-AUG-2009'; 

尝试显式转换(to_date ('31-AUG-2009', 'DD-MON-YYYY')代替,也许摆脱了这个问题。

如果没有帮助,你可以看到你的错误是在sp还是在你的代码中产生的?如果你不能直接看出来,从你的代码中定义一个sp,设置一个断点并遍历代码,看看错误来自哪里from。

There's no不看光标的查询是什么的方式。看看你在程序SP中运行的SELECT语句。在rec_type中选择一个数字字段的列之一是返回字符数据,该数据无法转换为数字。

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

在你的评论sayHere是错误:

ORA-06502: PL/SQL: numeric or value error ORA-06512: at line 16

不管它可能会出现像有些时候,不是随机生成的PL/SQL的错误。此错误指向您的过程的第16行中出现的有缺陷的数据类型转换。没有看到你的整个程序,我们不可能找出第16行。幸运的是,SQL Developer中的代码编辑器会将行号放入装订线中;如果您没有看到行号,则需要切换首选项。

你需要查找的是一个字符串被转换为数字或日期变量,或将数字转换为日期字段。这可以通过明确的TO_NUMBER()或TO_DATE来指示,在这种情况下,您需要检查格式掩码和/或数据内容。或者,你可能有一个隐式强制转换。在这种情况下,您可能需要使用适当的格式掩码来明确它。当然,由于SELECT语句的投影与REF CURSOR记录的签名不匹配,它可能是意外和不必要的转换。这很容易解决。

如果您有需要在proc的签名一个指针的程序,你可以这样做:

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

选中,然后按F5。