如何在SQL oracle 11g中获取一个函数在另一个函数中的结果?

wribegjk  于 2023-06-22  发布在  Oracle
关注(0)|答案(2)|浏览(113)

就像这样行不通

create FUNCTION getSomt RETURN sys_refcursor is
    vResult sys_refcursor;
BEGIN
    open vResult for
        select 'Y' as field from dual;
    return vResult;
END getSomt;

create FUNCTION doWork RETURN sys_refcursor is
    vResult sys_refcursor;
BEGIN
    open vResult for
        select * from getSomt() where field = 'N';
    return vResult;
END doWork;

也许是像使用批量收集?但我不知道该怎么做

mu0hgdu0

mu0hgdu01#

像这样:

SQL> CREATE OR REPLACE FUNCTION getSomt
  2     RETURN SYS_REFCURSOR
  3  IS
  4     vResult  SYS_REFCURSOR;
  5  BEGIN
  6     OPEN vResult FOR SELECT 'Y' AS field FROM DUAL;
  7
  8     RETURN vResult;
  9  END getSomt;
 10  /

Function created.

SQL> CREATE OR REPLACE FUNCTION doWork
  2     RETURN SYS_REFCURSOR
  3  IS
  4     vResult  SYS_REFCURSOR;
  5  BEGIN
  6     vResult := getSomt;                   --> here
  7     RETURN vResult;
  8  END doWork;
  9  /

Function created.

测试:

SQL> SELECT dowork FROM DUAL;

DOWORK
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

F
-
Y

SQL>

[编辑,基于您的评论]

如果涉及到额外的逻辑,首先必须fetch到本地声明的变量中,处理结果,将其存储到另一个变量中(我选择了内置的sys.odcivarchar2list类型,因为它适合这种需要)并返回结果。
第一个函数保持原样(我添加了另一行,字段值为N):

SQL> CREATE OR REPLACE FUNCTION getSomt
  2     RETURN SYS_REFCURSOR
  3  IS
  4     vResult  SYS_REFCURSOR;
  5  BEGIN
  6     OPEN vResult FOR SELECT 'Y' AS field FROM DUAL
  7                      UNION ALL
  8                      SELECT 'N' FROM DUAL;
  9
 10     RETURN vResult;
 11  END getSomt;
 12  /

Function created.

doWork显著改变:

SQL> CREATE OR REPLACE FUNCTION doWork
  2     RETURN SYS.odcivarchar2list
  3  IS
  4     vResult  SYS_REFCURSOR;
  5     --
  6     l_field  VARCHAR2 (1);
  7     retval   SYS.odcivarchar2list := sys.odcivarchar2list ();
  8  BEGIN
  9     vResult := getSomt;
 10
 11     LOOP
 12        FETCH vResult INTO l_field;
 13
 14        EXIT WHEN vResult%NOTFOUND;
 15
 16        IF l_field = 'N'
 17        THEN
 18           retval.EXTEND;
 19           retval (retval.COUNT) := l_field;
 20        END IF;
 21     END LOOP;
 22
 23     RETURN retval;
 24  END doWork;
 25  /

Function created.

测试:

SQL> SELECT dowork FROM DUAL;

DOWORK
--------------------------------------------------------------------------------
ODCIVARCHAR2LIST('N')

SQL>
9w11ddsr

9w11ddsr2#

您可以使用XMLTYPE读取游标,然后使用XMLTABLE解析它,并使用它生成另一个游标:

create FUNCTION getSomt RETURN sys_refcursor is
    vResult sys_refcursor;
BEGIN
    open vResult for
        select 'Y' as field from dual UNION ALL
        select 'N' as field from dual;
    return vResult;
END getSomt;
/

create FUNCTION doWork RETURN sys_refcursor is
    vResult sys_refcursor;
BEGIN
    open vResult for
        select *
        from   XMLTABLE(
                 'ROWSET/ROW'
                 PASSING XMLTYPE(getSomt())
                 COLUMNS
                   field VARCHAR2(1) PATH './FIELD'
                 
               )
        where  field = 'N';
    return vResult;
END doWork;
/

然后你可以调用它使用:

DECLARE
  v_field VARCHAR2(1);
  v_cur   SYS_REFCURSOR := doWork();
BEGIN
  LOOP
    FETCH v_cur INTO v_field;
    EXIT WHEN v_cur%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(v_field);
  END LOOP;
END;
/

其输出:

N

fiddle

相关问题