如何从 PLSQL 函数 ORACLE 中的 returns 游标创建 select
How to make a select from a cursor that returns from a plsql function ORACLE
我有一个功能return一个游标我的包是这样的
FUNCTION SEDIRUNTIME (sede varchar2) return SYS_REFCURSOR
此游标 return x 只有一个值的行数,例如:
ROW1 - 34
ROW2 - 55
ROW3 - 56 ecc. ecc.
现在我 select 这样
.. AND field in (select DBK_ENIN_REPORT.*SEDIRUNTIME*(sede) from dual)
这将模拟一个子句 IN 我们可以知道 运行 时间的值。
例如,根据位置参数,光标可以给我 22 和 34 而不仅仅是 56 或 78 98 09。
这样写我无法处理错误编号 00932 不连贯的数据类型。
解决方案?
你不能像那样使用 CURSOR
。
但是你可以把函数改成return一个集合:
CREATE TYPE Numberlist IS TABLE OF NUMBER;
/
CREATE FUNCTION DBK_ENIN_REPORT.SEDIRUNTIME (
sede varchar2
) return NumberList
IS
out_numbers NumberList;
BEGIN
SELECT id
BULK COLLECT INTO out_numbers
FROM your_table;
RETURN out_numbers;
END;
/
那么你可以这样做:
.. AND field MEMBER OF DBK_ENIN_REPORT.SEDIRUNTIME(sede)
或
.. AND field IN ( SELECT COLUMN_VALUE FROM TABLE( DBK_ENIN_REPORT.SEDIRUNTIME(sede) ) )
好吧,我会说你 CAN
做到了,但你需要 twist
一点。您可以在下面看到我是如何做到的。我以员工 table 为例。
创建函数:
CREATE OR REPLACE FUNCTION SEDIRUNTIME (sede VARCHAR2)
RETURN SYS_REFCURSOR
AS
cur SYS_REFCURSOR;
BEGIN
OPEN cur FOR SELECT employee_id FROM employee;
RETURN cur;
END;
/
匿名块,您可以在程序包中将其作为过程实现;
DECLARE
x SYS_REFCURSOR;
y NUMBER;
v VARCHAR2 (100);
v_sql VARCHAR2 (200);
TYPE var_emp IS TABLE OF employee%ROWTYPE
INDEX BY PLS_INTEGER;
v_emp var_emp;
BEGIN
x := SEDIRUNTIME ('sede');
LOOP
FETCH x INTO y;
v := v || ',' || y;
EXIT WHEN x%NOTFOUND;
END LOOP;
--Created the IN clause list
v := LTRIM (v, ',');
v_sql := 'Select * from employee where employee_id in (' || v || ')';
EXECUTE IMMEDIATE v_sql BULK COLLECT INTO v_emp;
FOR i IN 1 .. v_emp.COUNT
LOOP
DBMS_OUTPUT.put_line ( v_emp (i).employee_id || '--' || v_emp (i).first_name);
END LOOP;
END;
输出:
SQL> /
1--XXX
2--YYY
PL/SQL procedure successfully completed.
SQL>
PS:当然MTO提供的解决方案会比这个快很多。
我有一个功能return一个游标我的包是这样的
FUNCTION SEDIRUNTIME (sede varchar2) return SYS_REFCURSOR
此游标 return x 只有一个值的行数,例如:
ROW1 - 34
ROW2 - 55
ROW3 - 56 ecc. ecc.
现在我 select 这样
.. AND field in (select DBK_ENIN_REPORT.*SEDIRUNTIME*(sede) from dual)
这将模拟一个子句 IN 我们可以知道 运行 时间的值。
例如,根据位置参数,光标可以给我 22 和 34 而不仅仅是 56 或 78 98 09。
这样写我无法处理错误编号 00932 不连贯的数据类型。
解决方案?
你不能像那样使用 CURSOR
。
但是你可以把函数改成return一个集合:
CREATE TYPE Numberlist IS TABLE OF NUMBER;
/
CREATE FUNCTION DBK_ENIN_REPORT.SEDIRUNTIME (
sede varchar2
) return NumberList
IS
out_numbers NumberList;
BEGIN
SELECT id
BULK COLLECT INTO out_numbers
FROM your_table;
RETURN out_numbers;
END;
/
那么你可以这样做:
.. AND field MEMBER OF DBK_ENIN_REPORT.SEDIRUNTIME(sede)
或
.. AND field IN ( SELECT COLUMN_VALUE FROM TABLE( DBK_ENIN_REPORT.SEDIRUNTIME(sede) ) )
好吧,我会说你 CAN
做到了,但你需要 twist
一点。您可以在下面看到我是如何做到的。我以员工 table 为例。
创建函数:
CREATE OR REPLACE FUNCTION SEDIRUNTIME (sede VARCHAR2)
RETURN SYS_REFCURSOR
AS
cur SYS_REFCURSOR;
BEGIN
OPEN cur FOR SELECT employee_id FROM employee;
RETURN cur;
END;
/
匿名块,您可以在程序包中将其作为过程实现;
DECLARE
x SYS_REFCURSOR;
y NUMBER;
v VARCHAR2 (100);
v_sql VARCHAR2 (200);
TYPE var_emp IS TABLE OF employee%ROWTYPE
INDEX BY PLS_INTEGER;
v_emp var_emp;
BEGIN
x := SEDIRUNTIME ('sede');
LOOP
FETCH x INTO y;
v := v || ',' || y;
EXIT WHEN x%NOTFOUND;
END LOOP;
--Created the IN clause list
v := LTRIM (v, ',');
v_sql := 'Select * from employee where employee_id in (' || v || ')';
EXECUTE IMMEDIATE v_sql BULK COLLECT INTO v_emp;
FOR i IN 1 .. v_emp.COUNT
LOOP
DBMS_OUTPUT.put_line ( v_emp (i).employee_id || '--' || v_emp (i).first_name);
END LOOP;
END;
输出:
SQL> /
1--XXX
2--YYY
PL/SQL procedure successfully completed.
SQL>
PS:当然MTO提供的解决方案会比这个快很多。