来自UDF的TOAD Oracle SQL返回行

时间:2013-06-17 13:32:50

标签: plsql toad

下面有一个函数返回一个游标。但是我需要它只返回一行。我已经在google上阅读了关于将数据作为%rowtype返回的信息,但我似乎无法让它工作。

我不希望返回游标的原因是当我选择函数时,返回一个单元格,说(cursor)而不是显示一行包含4列数据。

create or replace function udf
(
    i_ptf_code in varchar2
    ,i_begin_date in date
    ,i_end_date in date
)

    return sys_refcursor

is
    portf_code varchar2(50);
    end_date date;
    chain_linked_ptf_net float;
    chain_linked_ptf_gross float;
    chain_linked_bmk float;
    end_mv float;
    v_cursor sys_refcursor;

    cursor c_return_series is
        select      p.portf_code
                    ,gpr.end_date
                    ,gpr.end_market_value
                    ,gpr.portf_perf_gross as gross_ret
                    ,gpr.portf_perf_net as net_ret
                    ,(exp(sum(ln(1 + gpr.portf_perf_gross)) over (partition by p.portf_code order by end_date)) - 1) as chain_linked_ptf_gross
                    ,(exp(sum(ln(1 + gpr.portf_perf_net)) over (partition by p.portf_code order by end_date)) - 1) as chain_linked_ptf_net
                    ,(exp(sum(ln(1 + gpr.bmk_perf)) over (partition by p.portf_code order by end_date)) - 1) as chain_linked_bmk
        from        portfolio_returns gpr
        inner join  portfolio p on p.portf_id = gpr.portf_id and p.is_composite != 2  --2 means composite
        where       p.portf_code = i_ptf_code
        and         gpr.end_date between i_begin_date and i_end_date;

begin

    select i_ptf_code, i_end_date into portf_code, end_date from dual; 

    for c1line in c_return_series loop

        if c1line.end_date = i_end_date then
            select  c1line.chain_linked_ptf_gross
                    ,c1line.chain_linked_ptf_net
                    ,c1line.chain_linked_bmk
                    ,c1line.end_market_value
            into    chain_linked_ptf_gross
                    ,chain_linked_ptf_net
                    ,chain_linked_bmk
                    ,end_mv
            from    dual;
        end if;

    end loop;

    open v_cursor for

        select      portf_code as portf_code
                    ,end_date as end_date
                    ,chain_linked_ptf_gross * 100 as period_ptf_gross
                    ,chain_linked_ptf_net * 100 as period_ptf_net
                    ,chain_linked_bmk * 100 as period_bmk
                    ,end_mv * 100 as period_mv
        from        dual;

    return v_cursor;
    close v_cursor;

end;
/

1 个答案:

答案 0 :(得分:0)

我有点失落,但我认为这就是你所需要的:

[...]
    open v_cursor for

        select      portf_code as portf_code
                    ,end_date as end_date
                    ,chain_linked_ptf_gross * 100 as period_ptf_gross
                    ,chain_linked_ptf_net * 100 as period_ptf_net
                    ,chain_linked_bmk * 100 as period_bmk
                    ,end_mv * 100 as period_mv
        from        dual;

    return v_cursor;
    -- close v_cursor; -- not needed

end;

-

DECLARE
    l_rc               SYS_REFCURSOR;
    l_portf_code       VARCHAR2(30);
    l_end_date         VARCHAR2(30);
    l_period_ptf_gross NUMBER;
    l_period_ptf_net   NUMBER;
    l_period_bmk       NUMBER;
    l_period_mv        NUMBER;
BEGIN
    l_rc := udf;  -- This returns an open cursor

    fetch v_rc into l_portf_code, l_end_date, l_period_ptf_gross, l_period_ptf_net, l_period_bmk, l_period_mv;

    DBMS_OUTPUT.PUT_LINE
    (
        l_portf_code       || ' ' ||
        l_end_date         || ' ' ||
        l_period_ptf_gross || ' ' ||
        l_period_ptf_net   || ' ' ||
        l_period_bmk       || ' ' ||
        l_period_mv        
    );
    CLOSE v_rc;
END;