2016-02-05 2 views
1

Я написал процедуру в PL/SQL и хочу вернуть объект типа EMP. Можно ли это сделать? Если да, как я могу это сделать?Как установить объект как параметр out?

Вот код:

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; 
    /

Я хочу, чтобы получить ename и empno, наконец, после обновления в процедуре. Как я могу это сделать? Если есть лучший способ сделать это, пожалуйста, предложите мне.

А также, пожалуйста, предложите мне, как я могу это сделать. Я не могу использовать какие-либо функции здесь, это единственное обязательство. Также, пожалуйста, дайте мне знать, если есть способ сделать это с помощью.

+1

Как 'emp_det' объявлен? Вы сказали, что это объект, но тогда 'l_cursor' предполагает, что это курсор? –

+0

emp_det - тип объекта, который я создал. Он имеет два атрибута ename и empo. Если я использую lcursor как refcursor, есть способ вернуть набор записей через него. –

ответ

0

В вашем примере (Table EMP) единицу записи EMP не следует выбирать по номеру отдела. Вместо этого используйте EMPNO.

Ниже быстрое решение, и мы надеемся себя объяснима:

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; 

Выход:

---- Single EMP ---- 
test | 7369 
---- EMP List ---- 
TEST | 7499 
TEST | 7521 
TEST | 7654 
TEST | 7698 
TEST | 7844 
TEST | 7900 

SQL>