简体   繁体   中英

How to define a pipelined table function within a with statement?

It's possible to defined a function within a with statement ( How to define a function and a query in the same with block? ). But I fail to define a pipelined function inside a with statement.

WITH
    FUNCTION f (a IN INTEGER)
        RETURN SYS.odcinumberlist
        PIPELINED
    IS
        ret   INTEGER;
    BEGIN
        FOR z IN 1 .. a
        LOOP
            PIPE ROW (z);
        END LOOP;

        RETURN;
    END;
SELECT * FROM f(3);  --I tried with table(f(3)) too

[Error] Execution (2: 1): ORA-06553: PLS-653: aggregate/table functions are not allowed in PL/SQL scope

Is it possible to define a pipelined table function within a with statement and how?

If it is possible, I would like to do that with a table of record. Therefore I need to know how defined type within a with statement too.

Within a subquery-factoring clause, you can make a non-pipelined function that returns a collection:

WITH FUNCTION f (a IN INTEGER)
  RETURN SYS.ODCINUMBERLIST
IS
  v_list SYS.ODCINUMBERLIST := SYS.ODCINUMBERLIST();
BEGIN
  FOR z IN 1 .. a LOOP
    v_list.EXTEND;
    v_list(v_list.COUNT) := z;
  END LOOP;
  RETURN v_list;
END f;
SELECT *
FROM   TABLE(f(3)); 

Which outputs:

COLUMN_VALUE
1
2
3

db<>fiddle here


If it is possible, I would like to do that with a table of record.

A record is a PL/SQL data type; you cannot use it in an SQL statement. Instead use an OBJECT data type and declare it in the global SQL scope before you run your query (no, you cannot declare it locally inside your query).

Therefore I need to know how defined type within a with statement too.

Again, you cannot as the SQL syntax does not allow it. See the answer to your previous question .

You can declare it globally:

CREATE TYPE test_obj IS OBJECT (
  w1 INTEGER
);

CREATE TYPE test_obj_table IS TABLE OF test_obj;

WITH FUNCTION f (a IN INTEGER)
  RETURN test_obj_table
IS
  v_list test_obj_table := test_obj_table();
BEGIN
  FOR z IN 1 .. a LOOP
    v_list.EXTEND;
    v_list(v_list.COUNT) := test_obj(z);
  END LOOP;
  RETURN v_list;
END f;
SELECT *
FROM   TABLE(f(3)); 

Outputs:

W1
1
2
3

db<>fiddle here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM