簡體   English   中英

帶有游標參數oracle的流水線函數

[英]pipelined function with cursor parameter oracle

例如,如果我有這種功能

function test_pipe(p_source in t_cursor)
return t_tab
pipelined
as --some code goes here

t_cursor是一個引用游標。 我知道我可以稱這個功能為

select * from table(test_pipe(cursor(select 1 from dual)));

但是如果我在一個包中聲明游標並希望將其作為參數傳遞該怎么辦呢。 這樣的事情。

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;

我得到main_cur無效的標識符 - pl / sql:ORA00904錯誤。 我應該如何編寫能夠將main_cur作為參數傳遞給test_pipe?

cursor main_cur從dual中選擇1;

游標是用於從結果集中獲取行的指針。

所以,當你做table(test_pipe(main_cur))你是不是傳遞一個行源流水線功能 您需要先獲取行然后傳遞rowsource。

測試用例:

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>

管道功能

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>

現在,讓我們測試一下流水線函數

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>

游標表達式等效於ref游標。 顯式游標是不同的,不可互換; 您可以使用dbms_sql包在ref游標和游標變量之間進行一些交換,但不能使用這樣的顯式游標進行交換。

我能看到的最接近你想要的是一個游標變量,用`open for syntax打開相同的查詢:

procedure test is
  v_ct pls_integer;
  main_cur t_cursor;
begin
  open main_cur for select 1 from dual;
  select count(*) into v_ct from table(test_pipe(main_cur));
  close main_cur;
  dbms_output.put_line('Count is: ' || v_ct);
  --some code
end test;

但這不是一回事,所以可能不合適。 我不知道你為什么要使用顯式游標而不是循環覆蓋它。


因為這與你最初提出的問題沒有任何關系,所以在這里直接進入XY領域,但是從評論中你似乎希望能夠聚合光標中的數據; 你可以用分析計數來做到這一點。 作為一個非常簡單的示例,如果您的游標查詢正在執行:

select trace, col1
from t42
order by trace, col1;

然后你可以添加另一列來計算每個跟蹤值:

select trace, col1,
  count(col1) over (partition by trace) as trace_count
from t42
order by trace, col1;

然后,您可以引用游標循環中的列。 或者,如果您只想循環計數為1的行,您的游標可以將其用作子查詢:

select trace, col1
from (
  select trace, col1,
    count(col1) over (partition by trace) as trace_count
  from t42
)
where trace_count = 1
order by trace, col1;

SQL小提琴演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM