【问题标题】:Oracle PL/SQL Return recordset and specific column(from recordset) in seperate variableOracle PL/SQL 在单独的变量中返回记录集和特定列(来自记录集)
【发布时间】:2020-04-25 19:34:24
【问题描述】:

我需要从过程、记录集和单个值中返回值(从记录集中提取)

CREATE TABLE EMP
(
    EMP_ID number;
    EMP_NAME varchar2(20);
    EMP_FLAG char(1);
);

CREATE TABLE SALARY
(
    EMP_ID number;
    EMP_SAL number;
);

BEGIN
  insert into EMP values(10,'John','N');
  insert into EMP values(20,'May','Y');

  insert into SALARY values(10,10000);
  insert into SALARY values(10,25000);
END;
/

这是我的程序

CREATE OR REPLACE PROCEDURE TEST(Flag in char(1),curEMP out SYS_REFCURSOR,Sal out number)
  v_sal    number;   
  v_emp_id number;
  v_name   varchar2(20);                               
AS
    open curEMP for
    select e.emp_id
            ,e.emp_name
            ,s.sal
    from emp e
    left join sal s on e.emp_id  = s.emp_id
    where e.emp_flag = Flag;

    loop
        fetch curEMP into v_emp_id,v_name,v_Sal; --in real life there are more than 20+ fields
      exit when curEMP%notfound;
    end loop;
    Sal := v_sal;
END TEST;
/

调用过程的脚本

set serveroutput on;
variable cr refcursor;
variable sal number;

exec TEST('Y',:cr,:sal);
print cr;
print sal;

这是输出

输出

sal
25000

但是,我需要这样的输出

--从光标列表输出

emp_id emp_name sal     
20     May   25000

--来自sal变量

sal     
25000

【问题讨论】:

  • 这里有两个问题:首先,当您返回一个 REF CURSOR 时,您应该打开它但不能从中获取。调用您的程序应该进行提取,然后关闭游标。其次,如果您的查询返回多于一行,那么这些行可能会以任何顺序返回,因此 SAL 的内容可能会发生变化。您需要进行单独的查询以获得调用者想要的准确 SAL 值。
  • 感谢您的建议,我现在尝试按照您的指示进行操作。

标签: oracle stored-procedures plsql oracle12c


【解决方案1】:

您的表 DDL 和过程存在多个问题,但我猜您还是执行了该过程。

要获取所有记录,您可以使用唯一的cursor 并在procedure 中打开它,不需要looping 通过cursor 在您的procedure 中。

请参阅以下示例中的 procedure 及其调用:

SQL> CREATE OR REPLACE PROCEDURE TEST (
  2      FLAG     IN       CHAR, -- size can not be given in the input parameter
  3      CUREMP   OUT      SYS_REFCURSOR
  4      --SAL      OUT      NUMBER -- no need of this parameter
  5  ) AS
  6      --V_SAL      NUMBER; -- all variables are not needed
  7      --V_EMP_ID   NUMBER;
  8      --V_NAME     VARCHAR2(20);
  9  BEGIN
 10      OPEN CUREMP FOR SELECT
 11                          E.EMP_ID,
 12                          E.EMP_NAME,
 13                          S.EMP_SAL
 14                      FROM
 15                          EMP E
 16                          LEFT JOIN SALARY S ON E.EMP_ID = S.EMP_ID
 17                      WHERE E.EMP_FLAG = FLAG;
 18  --    LOOP -- looping is not needed
 19  --        FETCH CUREMP INTO
 20  --            V_EMP_ID,
 21  --            V_NAME,
 22  --            V_SAL; --in real life there are more than 20+ fields
 23  --        EXIT WHEN CUREMP%NOTFOUND;
 24  --    END LOOP;
 25
 26  --    SAL := V_SAL;
 27  END TEST;
 28  /

Procedure created.

SQL>

现在测试程序。

SQL> VAR x REFCURSOR;
SQL> exec test('Y',:x);

PL/SQL procedure successfully completed.

SQL> print :x

    EMP_ID EMP_NAME                EMP_SAL
---------- -------------------- ----------
        20 May                       25000

SQL>

干杯!!

【讨论】:

  • 感谢您的帮助。但是,我需要显示 2 个变量。首先,VAR x REFCURSOR;与您的输出相同(记录集 emp_id、emp_name、emp_sal)。第二个变量,只有 1 列,sal 存储 25000
  • 但是你把它放在游标里那为什么你又想把它放在不同的变量里呢?
  • 对不起,我不知道原因。但是,这是另一个团队的要求。
  • @SNPalita 如果您希望将所有变量分开,则需要显式声明变量。
猜你喜欢
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 2018-01-09
  • 2011-03-03
  • 1970-01-01
  • 2023-03-23
相关资源
最近更新 更多