我试图在存储过程中返回一个表。这就是我到目前为止所拥有的

时间:2015-03-22 15:48:20

标签: oracle procedure

我的目标是使用存储过程返回一个表。

create or replace PACKAGE EMPLOYEE_DETAILS AS

    TYPE DETAILS IS RECORD(
      EMPLOYEE_FIRST_NAME VARCHAR2(20),
      EMPLOYEE_LAST_NAME VARCHAR2(25),
      EMPLOYEE_ID NUMBER(6,0) 
      );

    TYPE TABLE_EMPLOYEES IS TABLE OF DETAILS;

    PROCEDURE GET_EMPLOYEES(
    EMP_DEPT_ID EMPLOYEES.DEPARTMENT_ID%TYPE,
    EMP_SALARY employees.salary%TYPE,
    P_TBL_EMPLOYEES OUT L_TABLE_EMPLOYEES
    );

    FUNCTION IS_EMPLOYEE(EMP_ID EMPLOYEES.EMPLOYEE_ID%TYPE)
    RETURN BOOLEAN;

    END EMPLOYEE_DETAILS;

这是包体。我编译时遇到错误。我没有包含函数IS_EMPLOYEES的详细信息,但它返回一个布尔值。我是oracle编程的初学者。有人可以指导我解决这个问题吗?

 create or replace PACKAGE BODY EMPLOYEE_DETAILS AS

    PROCEDURE GET_EMPLOYEES(
    EMP_DEPT_ID EMPLOYEES.DEPARTMENT_ID%TYPE, 
    EMP_SALARY employees.salary%TYPE,
    P_TBL_EMPLOYEES OUT L_TABLE_EMPLOYEES
    )

    IS
    LC_SELECT SYS_REFCURSOR
    LR_DETAILS DETAILS;
    P_TBL_EMPLOYEES L_TABLE_EMPLOYEES;

    BEGIN
    OPEN LC_SELECT FOR 
    SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME FROM EMPLOYEES
    WHERE DEPARTMENT_ID=EMP_DEPT_ID
    AND
    EMPLOYEES.SALARY>EMP_SALARY;

    LOOP 
    FETCH LC_SELECT INTO LR_DETAILS;
    EXIT WHEN LC_SELECT%NOTFOUND;

    IF IS_EMPLOYEE(LR_DETAILS.EMPLOYEE_ID) THEN
    INSERT INTO P_TBL_EMPLOYEES VALUES(LR_DETAILS.EMPLOYEE_ID,LR_DETAILS.EMPLOYEE_FIRST_NAME,DETAILS.EMPLOYEE_LAST_NAME);

    END IF;
    END LOOP;
    CLOSE LC_SELECT;

    END GET_EMPLOYEES;
    END EMPLOYEE_DETAILS; 

1 个答案:

答案 0 :(得分:1)

不完整的逻辑有点令人困惑:假设您从EMPLOYEES表中选择IS_EMPLOYEE()如何返回除true以外的任何内容?

无论如何,你的实际问题是INSERT被保留用于填充堆(永久)表。 TBL_EMPLOYEES是一个集合,一个内存结构,因此需要像任何其他变量一样对待。

填充集合的最简单方法是使用SELECT ... BULK COLLECT INTO语法。 Find out more。但是,我将提供符合您逻辑的解决方案:

PROCEDURE GET_EMPLOYEES(
    EMP_DEPT_ID EMPLOYEES.DEPARTMENT_ID%TYPE, 
    EMP_SALARY employees.salary%TYPE,
    TBL_EMPLOYEES OUT TABLE_EMPLOYEES
)

IS
    LC_SELECT SYS_REFCURSOR
    LR_DETAILS DETAILS;
    TBL_EMPLOYEE TABLE_EMPLOYEES;

BEGIN
    OPEN LC_SELECT FOR 
        SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME 
        FROM EMPLOYEES
        WHERE DEPARTMENT_ID=EMP_DEPT_ID
        AND EMPLOYEES.SALARY>EMP_SALARY;

    LOOP 
        FETCH LC_SELECT INTO LR_DETAILS;
        EXIT WHEN LC_SELECT%NOTFOUND;

        IF IS_EMPLOYEE(LR_DETAILS.EMPLOYEE_ID) THEN
            TBL_EMPLOYEE.extend();
            TBL_EMPLOYEE(TBL_EMPLOYEE.count()) := LR_DETAILS;
        END IF;
    END LOOP;
    CLOSE LC_SELECT;
    TBL_EMPLOYEES := TBL_EMPLOYEE;

END GET_EMPLOYEES;

顺便说一句,您应该努力清楚地区分局部变量和参数的名称:TBL_EMPLOYEESTBL_EMPLOYEE太相似了。 P_TBL_EMPLOYEESL_TBL_EMPLOYEE简单明了,采用这样的命名约定会使调试代码变得更加容易。