[英]Oracle 12c: Can I invoke a function from a WITH clause which both takes and returns a table?
I want to write a PL/SQL function which can be used in a variety of queries, particular the subqueries of a WITH clause. 我想编写一个PL / SQL函数,该函数可用于各种查询,尤其是WITH子句的子查询。 The tricky part is that I want the function to both receive and return a one-column TABLE (or CURSOR) of information.
棘手的部分是我希望函数同时接收和返回信息的单列表(或CURSOR)。
Details: imagine that this function just sorts a list of employee IDs according to some very complicated criteria. 详细信息:假设此功能只是根据一些非常复杂的标准对员工ID列表进行排序。 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; 现在,我认为几乎可以在任何地方使用TABLE运算符使用函数的输出了; 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? 问题是:如何从“ wanted_emps”获取雇员列表,并将其作为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. 请注意 ,我希望在普通SQL中使用它,尤其是在如上所述的WITH子句的子查询中使用-而不是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: 这是一个如何将值收集到一个集合中的示例,然后可以
COLLECT
集合传递给返回另一个集合的FUNCTION
:
Oracle Setup : Oracle安装程序 :
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
SQUARED_VALUE\n--: |
-:| ------------:
------------:\n 1 |
1 | 1
1个\n 1 |
1 | 4
4\n 1 |
1 | 9
9\n 2 |
2 | 16
16\n 2 |
2 | 25
25\n 3 |
3 | 36
36\n
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.