例如,如果我有这种功能
function test_pipe(p_source in t_cursor)
return t_tab
pipelined
as --some code goes here
Run Code Online (Sandbox Code Playgroud)
t_cursor 是一个引用游标。我知道我可以这样调用这个函数
select * from table(test_pipe(cursor(select 1 from dual)));
Run Code Online (Sandbox Code Playgroud)
但是如果我在包中声明游标并希望将其作为参数传递,该怎么办?像这样的东西。
procedure test is
v_ct pls_integer;
cursor main_cur is select 1 from dual;
begin
select count(*) into v_ct from table(test_pipe(main_cur));
--some code
end;
Run Code Online (Sandbox Code Playgroud)
我得到 main_cur 无效标识符 - pl/sql:ORA00904 错误。我应该如何编码才能将 main_cur 作为参数传递给 test_pipe?
光标main_cur是select 1 from Dual;
游标是用于从结果集中获取行的指针。
因此,当您这样做时table(test_pipe(main_cur)),您并没有将行源传递给管道函数。您需要首先获取行,然后传递行源。
测试用例:
SQL> CREATE or replace TYPE target_table_row
2 AS
3 OBJECT
4 ( EMPNO NUMBER(4) ,
5 ENAME VARCHAR2(10)
6 )
7 /
Type created.
SQL>
SQL> sho err
No errors.
SQL>
SQL> CREATE or replace TYPE target_table_rows
2 AS
3 TABLE OF target_table_row;
4 /
Type created.
SQL>
SQL> sho err
No errors.
SQL>
Run Code Online (Sandbox Code Playgroud)
管道功能
SQL> CREATE OR REPLACE FUNCTION pipelined_fx(
2 p_cursor IN SYS_REFCURSOR)
3 RETURN target_table_rows PIPELINED PARALLEL_ENABLE(
4 PARTITION p_cursor BY ANY)
5 IS
6 TYPE cursor_ntt
7 IS
8 TABLE OF emp%ROWTYPE;
9 nt_src_data cursor_ntt;
10 BEGIN
11 LOOP
12 FETCH p_cursor BULK COLLECT INTO nt_src_data LIMIT 100;
13 FOR i IN 1 .. nt_src_data.COUNT
14 LOOP
15 PIPE ROW (target_table_row( nt_src_data(i).empno, nt_src_data(i).ename ));
16 END LOOP;
17 EXIT
18 WHEN p_cursor%NOTFOUND;
19 END LOOP;
20 CLOSE p_cursor;
21 RETURN;
22 END pipelined_fx;
23 /
Function created.
SQL>
SQL> show errors
No errors.
SQL>
Run Code Online (Sandbox Code Playgroud)
现在,让我们测试一下管道函数:
SQL> DECLARE
2 rc SYS_REFCURSOR;
3 num NUMBER;
4 BEGIN
5 OPEN RC FOR SELECT * FROM emp;
6 SELECT count(*) INTO num FROM TABLE(pipelined_fx(rc));
7 DBMS_OUTPUT.PUT_LINE( num || ' rows in total.' );
8 END;
9 /
14 rows in total.
PL/SQL procedure successfully completed.
SQL>
Run Code Online (Sandbox Code Playgroud)