I want to write a PL/SQL function which can be used in a variety of queries, particular the subqueries of a WITH clause. The tricky part is that I want the function to both receive and return a one-column TABLE (or CURSOR) of information.
Details: imagine that this function just sorts a list of employee IDs according to some very complicated criteria. We'd have this:
So far so good, I hope.
Now, I think that I can use the output of the function with the TABLE operator pretty much anywhere; eg:
WITH
wanted_emps AS (...), -- find employees we want, as table of emp_id
ranked_emps AS (
SELECT rownum() as rank, emp_id
FROM TABLE(SORT_EMPLOYEES(...???...))
),
...
The problem is: how can I get the list of employees from 'wanted_emps' and make it the input of SORT_EMPLOYEES? What goes in the "...???..." above? Is this even possible?
Please note that I want this to be used from plain SQL, especially from subqueries of WITH clauses as shown above -- not from PL/SQL. Thanks!
Here is an example of how to COLLECT
values into a collection which can then be passed to a FUNCTION
that returns another collection:
Oracle Setup :
CREATE TYPE numbers_table AS TABLE OF NUMBER;
CREATE TABLE test_data ( grp, value ) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 1, 2 FROM DUAL UNION ALL
SELECT 1, 3 FROM DUAL UNION ALL
SELECT 2, 4 FROM DUAL UNION ALL
SELECT 2, 5 FROM DUAL UNION ALL
SELECT 3, 6 FROM DUAL;
Query :
WITH FUNCTION square( i_numbers IN numbers_table ) RETURN numbers_table
IS
p_numbers numbers_table := numbers_table();
p_count PLS_INTEGER;
BEGIN
IF i_numbers IS NULL THEN
p_count := 0;
ELSE
p_count := i_numbers.COUNT;
END IF;
p_numbers.EXTEND( p_count );
FOR i IN 1 .. p_count LOOP
p_numbers(i) := i_numbers(i) * i_numbers(i);
END LOOP;
RETURN p_numbers;
END;
collected_rows ( grp, grouped_values ) AS (
SELECT grp,
CAST(
COLLECT( value ORDER BY value )
AS numbers_table
)
FROM test_data
GROUP BY grp
)
SELECT c.grp,
t.COLUMN_VALUE AS squared_value
FROM collected_rows c
CROSS JOIN
TABLE( square( c.grouped_values ) ) t;
Output :
\nGRP | SQUARED_VALUE \n--: | ------------: \n 1 | 1 \n 1 | 4 \n 1 | 9 \n 2 | 16 \n 2 | 25 \n 3 | 36 \n
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.