【问题标题】:Pipelining Between PL/SQL Table FunctionsPL/SQL 表函数之间的流水线
【发布时间】:2021-07-26 16:41:58
【问题描述】:

我有一个包含 2 个流水线函数的包。当我尝试用另一个函数作为参数调用一个函数时,我收到“ORA-06553: PLS-306: wrong number or types of arguments in call”错误。

这是包裹:

create or replace NONEDITIONABLE TYPE RESULTING_RECORD_RT as object
   (
          CALENDAR  NVARCHAR2(1024), 
          PRODUCT   NVARCHAR2(1024), 
          MEASURE   NVARCHAR2(1024), 
          VALUE     NUMBER
   );
/
create or replace NONEDITIONABLE TYPE RESULTING_COLS_RT IS TABLE OF RESULTING_RECORD_RT;
/
create or replace package pipe_pkg as
function pipe_func_emp return RESULTING_COLS_RT PIPELINED;
function pipe_func_emp2(input_Set IN resulting_cols_rt) return RESULTING_COLS_RT PIPELINED;
end;
/
create or replace package body pipe_pkg as
function pipe_func_emp return RESULTING_COLS_RT
PIPELINED
is
    test_tbl resulting_cols_rt:= resulting_cols_rt();
begin
    test_tbl.extend;
    test_tbl(1):=resulting_record_rt('A','B','C',1);
    test_tbl.extend;
    test_tbl(2):=resulting_record_rt('A','B','D',2);
    PIPE ROW(test_tbl(1));
    PIPE ROW(test_tbl(2));
    return;
end;
function pipe_func_emp2(input_Set IN resulting_cols_rt) return RESULTING_COLS_RT
PIPELINED
is
    v_tmp NVARCHAR2(10240);
    l_res SYS_REFCURSOR;
    recs resulting_record_rt;
begin
    open l_res for select * from table(input_Set);
    loop
        fetch l_res into recs;
        PIPE ROW(recs);
        exit when l_res%notfound;
    end loop;
    close l_res;
    return;
end;
end;
/

我调用函数如下:

select * from TABLE(pipe_pkg.pipe_func_emp2(CURSOR(select * from TABLE(pipe_pkg.pipe_func_emp()))));

并且调用抛出错误:

ORA-06553: PLS-306: wrong number or types of arguments in call to 'PIPE_FUNC_EMP2'
06553. 00000 -  "PLS-%s: %s"

我做错了什么?

【问题讨论】:

    标签: oracle plsql plsql-package pipelined-function


    【解决方案1】:

    函数pipe_func_emp2 期望RESULTING_COLS_RT 作为它的参数,但得到了REF CURSOR。这些是不兼容的类型。

    尝试关注reproducible example 的流水线函数链接:

    create or replace type somerow  as object (id int, val varchar2 (8))
    /
    create or replace type sometab is table of somerow
    /
    create or replace package pack as
        function func1 return sometab pipelined;
        function func2 (cur sys_refcursor) return sometab pipelined;
    end;
    /
    create or replace package body pack as
        function func1 return sometab pipelined is
            tab sometab := sometab (somerow (1,'AAA'), somerow (2,'BBB'));
        begin
            for i in 1..tab.count loop 
                pipe row (tab(i)); 
            end loop;
            return;
        end;
        function func2 (cur sys_refcursor) return sometab pipelined is
            sr somerow;
        begin
            loop
                fetch cur into sr;
                exit when cur%notfound;
                pipe row (sr);
            end loop;
            close cur;
            return;
        end;
    end;
    /
    

    查询及其结果:

    select * 
    from table (pack.func2 (
        cursor (select value (p) from table (pack.func1()) p )))
    /
    
            ID VAL     
    ---------- --------
             1 AAA     
             2 BBB     
    

    【讨论】:

    • 不错。我试图在问题的示例上完成这项工作,但我无法实现。你有什么理由不以此为基础做你的榜样?
    • 谢谢。我得到了相同的结果,两个相同的行的值为 2。
    • 没关系。 EXIT WHEN cur%NOTFOUND; 只需要向上移动一行.. ;) 谈论花时间在错字上:D
    • 在 OP 的例子中同样的错误,我没有跟踪它;)
    • @brungel 是的,有可能(请参阅first revision of my answer)。我更改了它,因为选择完整的表格内容对流水线函数几乎没有意义。
    猜你喜欢
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多