如何将对象设置为out参数?

时间:2016-02-05 13:56:52

标签: sql oracle plsql

我在PL / SQL中编写了一个过程,想要返回一个EMP类型对象。有可能吗?如果是,我该怎么做?

以下是代码:

CREATE OR REPLACE
PROCEDURE get_emp_rs (p_deptno    IN  emp.deptno%TYPE,
                      p_recordset OUT emp_det) AS

    emp_details emp_det;
BEGIN 
  OPEN p_recordset FOR
    SELECT ename,
           empno
    FROM   emp
    WHERE  deptno = p_deptno
    ORDER BY ename;

   fetch p_recordset into emp_details; 
   --exit when p_recordset%notfound;
   --end loop;
   --for indx in p_recordset
   --loop
   emp_details.ename:= 'test';
   --end loop;
END get_emp_rs;
/

SET SERVEROUTPUT ON SIZE 1000000
    DECLARE
      l_cursor  emp_det;
      --l_cur emp_det;
      --l_ename   emp.ename%TYPE;
      --l_empno   emp.empno%TYPE;
      l_deptno  emp.deptno%TYPE;
    BEGIN
     l_cur:=get_emp_rs ('30',
                  l_cursor);
                dbms_output.put_line('low');
      /*LOOP 
        FETCH l_cursor
        INTO  l_ename, l_empno, l_deptno;
        EXIT WHEN l_cursor%NOTFOUND;*/
        DBMS_OUTPUT.PUT_LINE(l_cursor.ename || ' | ' || l_cursor.empno);
    end;
    /

我想在程序中最终更新后获得enameempno。 我该怎么做?如果有更好的方法,请建议我。

还请建议我如何以这种方式做到这一点。我不能在这里使用任何功能,这是唯一的义务。如果有办法使用,请告诉我。

1 个答案:

答案 0 :(得分:0)

在您的示例(表EMP)中,不应该通过部门编号选择单个EMP记录。请改用EMPNO。

以下是一个快速解决方案,希望可以自我解释:

Column == "" ? NULL(DT_WSTR,50) : Column

输出:

SET SERVEROUTPUT ON;
SET FEEDBACK OFF;
CLEAR;

--Define the dataset object
CREATE TYPE EMP_DET AS OBJECT (
 EMPNO NUMBER(4),
 ENAME VARCHAR2(10)
);
/

--Define a collection of dataset objects
CREATE TYPE EMP_DET_LIST IS TABLE OF EMP_DET;
/


--Get a SINGLE record into the OUT-Variable identified by EMP PK EMPNO
CREATE OR REPLACE PROCEDURE GET_EMP_RS(P_EMPNO     IN EMP.EMPNO%TYPE,
                                       P_RECORDSET IN OUT EMP_DET) AS
BEGIN
  --Create the return object inside SQL
  SELECT EMP_DET(EMPNO, ENAME)
  INTO   P_RECORDSET
  FROM   EMP
  WHERE  EMPNO = P_EMPNO;

  P_RECORDSET.ENAME := 'test';
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    --Return NULL if employee not found
    P_RECORDSET := NULL;
END GET_EMP_RS;
/

--Get a LIST OF employees by department
CREATE OR REPLACE PROCEDURE GET_EMP_LIST(P_DEPTNO     IN EMP.DEPTNO%TYPE,
                                         P_RECORDLIST OUT EMP_DET_LIST) AS
  TYPE C_CURSOR IS REF CURSOR; -- <-- For the explicit cursor solution only
  C_EMP_RS C_CURSOR;           -- <-- For the explicit cursor solution only
  V_RS     EMP_DET;            -- <-- For the explicit cursor solution only

BEGIN
  --Initialize out object
  P_RECORDLIST := EMP_DET_LIST();

  --Create the return object inside SQL
  --via bulk collect
  /*
  SELECT EMP_DET(EMPNO,ENAME)
  BULK COLLECT INTO INTO P_RECORDLIST
  FROM   EMP
  WHERE  DEPTNO = P_DEPTNO;
  */

  --with manipulation of records
  --use a FOR-LOOP with implizit cursor
  /*
  FOR L_RS IN (SELECT EMP_DET(EMPNO, ENAME) EMP_RS
               FROM   EMP
               WHERE  DEPTNO = P_DEPTNO) LOOP
    L_RS.EMP_RS.ENAME := 'TEST';
    P_RECORDLIST.EXTEND;
    P_RECORDLIST(P_RECORDLIST.LAST) := L_RS.EMP_RS;
    NULL;
  END LOOP;
  */

  --or define an explicit cursor and LOOP-FETCH

  OPEN C_EMP_RS FOR
    SELECT EMP_DET(EMPNO, ENAME) EMP_RS
    FROM   EMP
    WHERE  DEPTNO = P_DEPTNO;
  LOOP
    FETCH C_EMP_RS
      INTO V_RS;
    EXIT WHEN C_EMP_RS%NOTFOUND;
    V_RS.ENAME := 'TEST';
    P_RECORDLIST.EXTEND;
    P_RECORDLIST(P_RECORDLIST.LAST) := V_RS;
  END LOOP;
  CLOSE C_EMP_RS;

END GET_EMP_LIST;
/

--**************************
-- Test 
--**************************
DECLARE
  L_CURSOR EMP_DET;
  L_LIST   EMP_DET_LIST;
BEGIN

  DBMS_OUTPUT.PUT_LINE('---- Single EMP ----');

  GET_EMP_RS(7369, L_CURSOR);

  IF (L_CURSOR IS NOT NULL) THEN
    DBMS_OUTPUT.PUT_LINE(L_CURSOR.ENAME || ' | ' || L_CURSOR.EMPNO);
  END IF;

  DBMS_OUTPUT.PUT_LINE('---- EMP List ----');

  GET_EMP_LIST(30, L_LIST);

  IF (L_LIST.count > 0 ) THEN
    FOR L_I IN L_LIST.FIRST .. L_LIST.LAST LOOP
      DBMS_OUTPUT.PUT_LINE(L_LIST(L_I).ENAME || ' | ' || L_LIST(L_I).EMPNO);

    END LOOP;
  END IF;

END;
/


DROP PROCEDURE GET_EMP_RS;
DROP PROCEDURE GET_EMP_LIST;
DROP TYPE EMP_DET_LIST;
DROP TYPE EMP_DET;