有没有办法从游标中添加一个plsql表作为SELECT子句中的列?

问题描述 投票:0回答:2

我正在编写一个返回SYS_REFCURSOR CURSOR的plsql过程。

  PROCEDURE PRC_USER_APPS(o_total_rows    OUT NUMBER,
                          o_result_status OUT VARCHAR2,
                          o_cursor        OUT SYS_REFCURSOR);

我被当前的工作困扰,因为我需要添加从函数返回的plsql表或嵌套表作为SELECT游标中的一列。可以编写类似这样的代码吗?

OPEN o_cursor FOR
  SELECT id_application, usr.id_user, name_user, fnc_user_phone(usr.id_user)
  FROM   users usr,
         users_applications uap
  WHERE  usr.id_user = uap.id_user;

结果:

99909,001,“圣何塞·圣马丁”,{'mobilephone1',549351999999,'mobilephone2',54935188888}

新年快乐!!

oracle plsql cursor sys-refcursor
2个回答
1
投票

您需要了解“ plsql表”或“嵌套表”的含义。

Oracle文档将这种事情称为“集合”。您必须定义一个集合类型,然后进行该类型的集合。

有SQL收集类型和PL / SQL收集类型。

  • SQL集合类型来自CREATE TYPE ... AS TABLE语句
  • PL / SQL集合类型在PL / SQL代码中使用TYPE ... IS TABLE语句定义。
  • SQL语句(如SELECT)仅了解SQL收集类型!
  • PL / SQL代码可以使用SQL集合类型。
  • SQL集合可以是VARRAY或嵌套表。

在您的情况下,您根本不能在SELECT语句中使用“ plsql表”,但是如果它基于SQL类型,则可以使用“嵌套表”。

create or replace type t_phone as object(
  label varchar2(20),
  nbr integer
)
/
create or replace type tt_phone as table of t_phone
/
select d.*, tt_phone(t_phone('home',12345678), t_phone('work',23456789))
from dept d;

由于这些SQL类型,您将很难看到输出。此外,无论谁获取了您的ref游标,都必须也了解您的类型。这并不明显。

您可以通过使用CURSOR而不是嵌套表来简化事情:

select d.*, cursor(select empno, ename from emp where deptno = d.deptno) emps
from dept d;

DEPTNO DNAME        LOC       EMPS
    10 ACCOUNTING   NEW YORK  {<EMPNO=7782,ENAME=CLARK>,<EMPNO=7839,ENAME=KING>,<EMPNO=7934,ENAME=MILLER>,}
    20 RESEARCH     DALLAS    {<EMPNO=7369,ENAME=SMITH>,<EMPNO=7566,ENAME=JONES>,<EMPNO=7788,ENAME=SCOTT>,<EMPNO=7876,ENAME=ADAMS>,<EMPNO=7902,ENAME=FORD>,}
    30 SALES        CHICAGO   {<EMPNO=7499,ENAME=ALLEN>,<EMPNO=7521,ENAME=WARD>,<EMPNO=7654,ENAME=MARTIN>,<EMPNO=7698,ENAME=BLAKE>,<EMPNO=7844,ENAME=TURNER>,<EMPNO=7900,ENAME=JAMES>,}
    40 OPERATIONS   BOSTON    {}

0
投票

当然,只要SQL知道集合类型:

create or replace type number_tt as table of number;

((或使用现有类型-查询all_coll_types以查看已定义的内容。)

现在您可以在SQL中使用number_tt,例如:

select number_tt(1,2,3) as my_numbers from dual;

因此,如果您的函数返回number_tt,就没有问题:

create or replace function numberwang
    ( p1 number, p2 number, p3 number )
    return number_tt
as
begin
    return number_tt(p1,p2,p3);
end numberwang;
/

select numberwang(23,42,96) as my_numbers from dual;

这可以是ref游标的一部分,从程序等正常返回。

© www.soinside.com 2019 - 2024. All rights reserved.