我想在我的流水线函数中执行动态查询并返回此查询的结果。 是否有可能做到这一点? 流水线功能方便我为我的应用程序实现良好的界面,因为它的行为就像一个表。
功能:
CREATE OR REPLACE FUNCTION MyFunction(p_schema VARCHAR2) RETURN MyTableType Pipelined IS
v_query VARCHAR2(1000);
BEGIN
v_query := 'SELECT * FROM TABLE ('||p_schema||'.somepackage.SomeFunction)'; --SomeFunction is another pipelined function
EXECUTE IMMEDIATE v_query;
--Results of the v_query are compatible with MyTableType's row type. But how to return them from pipelined function?
END;
答案 0 :(得分:3)
可以组合动态SQL和流水线函数,但返回类型不是动态的:返回的列的数量和类型将是固定的。
您可以将EXECUTE IMMEDIATE
与BULK COLLECT
(感谢@be here now),dynamic cursors或DBMS_SQL
一起使用,以返回多行。以下是动态游标的示例:
SQL> CREATE OR REPLACE PACKAGE pkg AS
2 TYPE test_tab IS TABLE OF test%ROWTYPE;
3 FUNCTION dynamic_cursor(l_where VARCHAR2) RETURN test_tab PIPELINED;
4 END;
5 /
Package created.
SQL> CREATE OR REPLACE PACKAGE BODY pkg IS
2 FUNCTION dynamic_cursor(l_where VARCHAR2) RETURN test_tab PIPELINED IS
3 cc sys_refcursor;
4 l_row test%ROWTYPE;
5 BEGIN
6 OPEN cc FOR 'SELECT * FROM test WHERE ' || l_where;
7 LOOP
8 FETCH cc INTO l_row;
9 EXIT WHEN cc%NOTFOUND;
10 PIPE ROW (l_row);
11 END LOOP;
12 RETURN;
13 END;
14 END;
15 /
Package body created.
让我们称之为动态函数:
SQL> SELECT *
2 FROM TABLE(pkg.dynamic_cursor('id <= 2'));
ID DAT
---------- ---
1 xxx
2 xxx
与动态SQL一样,请注意SQL Injection。
答案 1 :(得分:1)
我认为是这样的:
CREATE OR REPLACE FUNCTION MyFunction(par1 VARCHAR2, ...) RETURN MyTableType Pipelined IS
v_query VARCHAR2(1000);
l_result MyTableType;
BEGIN
v_query := --My query created based on parameters
EXECUTE IMMEDIATE v_query into l_result;
pipe row(l_result);
END;
仅当v_query返回1行时才有效。
答案 2 :(得分:0)
我无法获得@VincentMalgrat的答案。但这非常接近。在正确的方向上对我绝对有很大帮助。
这就是我要工作的:
包装
CREATE OR REPLACE PACKAGE pkg AS
TYPE test_row IS RECORD ( test_name VARCHAR2 (255), test_number number, test_date date );
TYPE test_tab IS TABLE OF test_row;
FUNCTION dynamic_cursor(l_where VARCHAR2) RETURN test_tab PIPELINED;
END;
包装体
CREATE OR REPLACE PACKAGE BODY pkg IS
FUNCTION dynamic_cursor(l_where VARCHAR2) RETURN test_tab PIPELINED IS
cc sys_refcursor;
l_row test_row;
BEGIN
OPEN cc FOR 'select name_column, number_column, date_column FROM my_table where number_column ='||l_where;
LOOP
FETCH cc INTO l_row;
EXIT WHEN cc%NOTFOUND;
PIPE ROW (l_row);
END LOOP;
RETURN;
END;
END;