2015-10-12 37 views
1

我在执行存储过程以取回结果时遇到问题。目前,我想在toadeclipse的输出窗口中显示结果,或者我将要使用的任何其他结果。稍后,我想从程序中访问它们。现在忽略程序部分,除非它是必需的。从存储过程或函数获取结果

我有这个存储过程的代码:

create or replace procedure pottyuserange (p_date_format in varchar2, 
             p_start_date in varchar2, 
             p_end_date in varchar2, 
             p_ref_cursor out sys_refcursor) 
as 
begin 
    open p_ref_cursor for 
    select to_char(time_range, p_date_format) as current_date, 
     lm_search, 
     ao_search, 
     ro_search, 
     fl_search, 
     total 
from  (select trunc(time_range) time_range, 
        sum(case when porta_potty = 'LM' then 1 else 0 end) as lm_search, 
        sum(case when porta_potty = 'AO' then 1 else 0 end) as ao_search, 
        sum(case when porta_potty = 'RO' then 1 else 0 end) as ro_search, 
        sum(case when porta_potty = 'FL' then 1 else 0 end) as fl_search, 
        sum(case when porta_potty in ('LM', 'AO', 'RO', 'FL') then 1 else 0 end) as total   
      from  core.date_test 
      where trunc(time_range) >= to_date(p_start_date, p_date_format) 
      and  trunc(time_range) <= to_date(p_end_date, p_date_format) 
      group by trunc(time_range)) 
    order by time_range asc; 
    end pottyuserange; 
/

而且我试图得到这样的结果:

variable rc refcursor; 

BEGIN 
    pottyuserange('YYYY-MM-DD', '2008-10-1', '2010-10-12', :rc); 
END; 

print rc; 

这是我得到的错误:

ORA-01722: invalid number 
ORA-06512: at "core.pottyuserange", line 4 
ORA-06512: at line 1 

我该如何正确地访问这些数据,或将它变成User-Defined Function? \

这是我在把它变成一个功能的尝试:

create or replace function pottyuserange (p_date_format in varchar2, 
             p_start_date in varchar2, 
             p_end_date in varchar2) 
return result_set as rc sys_refcursor; 

BEGIN 

OPEN result_set FOR 
    select to_char(time_range, p_date_format) as current_date, 
     lm_search, 
     ao_search, 
     ro_search, 
     fl_search, 
     total 
from  (select trunc(time_range) time_range, 
        sum(case when porta_potty = 'LM' then 1 else 0 end) as lm_search, 
        sum(case when porta_potty = 'AO' then 1 else 0 end) as ao_search, 
        sum(case when porta_potty = 'RO' then 1 else 0 end) as ro_search, 
        sum(case when porta_potty = 'FL' then 1 else 0 end) as fl_search, 
        sum(case when porta_potty in ('LM', 'AO', 'RO', 'FL') then 1 else 0 end) as total   
      from  core.date_test 
      where trunc(time_range) >= to_date(p_start_date, p_date_format) 
      and  trunc(time_range) <= to_date(p_end_date, p_date_format) 
      group by trunc(time_range)) 
    order by time_range asc; 
    return result_set; 
    end pottyuserange; 
/

我与上面得到的错误是:PLS-00201: identifier 'RESULT_SET' must be declared

编辑TIME_RANGEDATEPORTA_POTTY是一个varchar2。

+0

,然后创建一个用户定义的函数,而不是一个存储过程。 –

+0

我更新了问题。我将如何将其转换为用户定义的函数?我一直在摆弄这个,但我没有运气。我会用我试过的东西来更新这篇文章。 –

+1

涉及的数据类型是什么?除非您的代码正在进行某种隐式转换,否则您得到的错误似乎没有多大意义。但是这种转换不会是明显的。我猜''time_range'是'date' –

回答

1

(方法1)创建自己的集合类型(S)和变化函数返回此类型的对象:

create or replace type tp_potty as object (
    current_date varchar2(20), lm_search number(6), ao_search number(6), 
    ro_search number(6), fl_search number(6), total number(6)); 

create or replace type tp_potty_tbl as table of tp_potty; 

create or replace function pottyuserange (p_date_format in varchar2, 
              p_start_date in varchar2, 
              p_end_date in varchar2) 
            return tp_potty_tbl is 
    potty_tbl tp_potty_tbl; 
begin 
    select cast(multiset(
     select to_char(time_range, p_date_format) as current_date, 
      lm_search, ao_search, ro_search, fl_search, total 
     from (select trunc(time_range) time_range, 
         sum(case when porta_potty = 'LM' then 1 else 0 end) lm_search, 
         sum(case when porta_potty = 'AO' then 1 else 0 end) ao_search, 
         sum(case when porta_potty = 'RO' then 1 else 0 end) ro_search, 
         sum(case when porta_potty = 'FL' then 1 else 0 end) fl_search, 
         sum(case when porta_potty in ('LM', 'AO', 'RO', 'FL') 
           then 1 else 0 end) total 
       from  date_test 
       where trunc(time_range) >= to_date(p_start_date, p_date_format) 
       and  trunc(time_range) <= to_date(p_end_date, p_date_format) 
       group by trunc(time_range)) 
     order by time_range asc) as tp_potty_tbl) into potty_tbl from dual; 
    return potty_tbl; 
end pottyuserange; 

现在运行:

select * from table(pottyuserange('yyyy-mm-dd', '2015-10-10', '2015-10-15')) 

CURRENT_DATE   LM_SEARCH AO_SEARCH RO_SEARCH FL_SEARCH TOTAL 
-------------------- --------- --------- --------- --------- ------- 
2015-10-12     1   0   0   0  1 
2015-10-13     1   0   0   0  1 
2015-10-14     0   0   0   0  0 

(方法2)从PL/SQL块中的函数返回的游标列表输出如下:

create or replace function potty2 (p_date_format in varchar2, 
    p_start_date in varchar2,p_end_date in varchar2) return sys_refcursor is 

    result_set sys_refcursor; 

BEGIN 

OPEN result_set FOR 
    select to_char(time_range, p_date_format) as current_date, 
     lm_search, ao_search, ro_search, fl_search, total 
from  (select trunc(time_range) time_range, 
        sum(case when porta_potty = 'LM' then 1 else 0 end) as lm_search, 
        sum(case when porta_potty = 'AO' then 1 else 0 end) as ao_search, 
        sum(case when porta_potty = 'RO' then 1 else 0 end) as ro_search, 
        sum(case when porta_potty = 'FL' then 1 else 0 end) as fl_search, 
        sum(case when porta_potty in ('LM', 'AO', 'RO', 'FL') 
          then 1 else 0 end) as total   
      from  date_test 
      where trunc(time_range) >= to_date(p_start_date, p_date_format) 
      and  trunc(time_range) <= to_date(p_end_date, p_date_format) 
      group by trunc(time_range)) 
    order by time_range asc; 
    return result_set; 
end potty2; 

PL/SQL块:

declare 
    cur sys_refcursor; 
    v1 varchar2(20); v2 number(6); v3 number(6); v4 number(6); v5 number(6); v6 number(6); 
begin 
    cur := potty2('yyyy-mm-dd', '2015-10-10', '2015-10-15'); 
    loop 
    fetch cur into v1, v2, v3, v4, v5, v6; 
    exit when cur%notfound; 
    dbms_output.put_line(v1||' '||v2||' '||v3||' '||v4||' '||v5||' '||v6); 
    end loop; 
    close cur; 
end; 

我的答案是基于这篇文章:PL/SQL 101 : Understanding Ref Cursors,如果你想在结果窗口结果

+0

谢谢。我实际上在几天前解决了这个问题,但忘了发布更新。问题是日期格式被错误地解析。明天,如果这有效,我会告诉你。 –