我正在尝试在存储过程中 return 一个 table。这是我到目前为止所拥有的

I am trying to return a table in stored procedure. This is what I have so far

我的目标是 return 一个 table 使用存储过程。

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 的详细信息,但它 return 是一个布尔值。我是 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; 

不完整的逻辑有点令人困惑:鉴于您是从 EMPLOYEES table 中选择的,IS_EMPLOYEE() return 除了 true 之外怎么可能?

无论如何,您的实际问题是 INSERT 保留用于填充堆(永久)tables。 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 简单明了,采用这样的命名约定将使调试代码变得无比容易。