【问题标题】:How to make a select from a cursor that returns from a plsql function ORACLE如何从从 plsql 函数 ORACLE 返回的游标中进行选择
【发布时间】:2017-10-05 09:16:46
【问题描述】:

我有一个返回光标的函数我的包是这样的

FUNCTION SEDIRUNTIME (sede varchar2) return SYS_REFCURSOR

此游标返回 x 行只有一个值,例如:

 ROW1 - 34
 ROW2 - 55
 ROW3 - 56  ecc. ecc.

现在我有我这样选择

.. AND field in  (select DBK_ENIN_REPORT.*SEDIRUNTIME*(sede) from dual)

这将模拟一个子句IN,我们可以在运行时知道它的值。

例如,根据位置参数,光标可以给我 22 和 34 而不仅仅是 56 或 78 98 09。

这样我就不能使用错误号 00932 不连贯的数据类型。

解决方案?

【问题讨论】:

标签: sql oracle plsql cursor


【解决方案1】:

你不能像那样使用CURSOR。

但是你可以改变函数来返回一个集合:

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) ) )

【讨论】:

    【解决方案2】:

    好吧,我会说你 CAN 去做,但你需要 twist 一点点。你可以看到我是如何做到的,如下所示。我以员工表为例。

    创建函数:

    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 提供的解决方案会比这个快很多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多