我正在尝试在存储过程中 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_EMPLOYEES
和 TBL_EMPLOYEE
太相似了。 P_TBL_EMPLOYEES
和 L_TBL_EMPLOYEE
简单明了,采用这样的命名约定将使调试代码变得无比容易。
我的目标是 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_EMPLOYEES
和 TBL_EMPLOYEE
太相似了。 P_TBL_EMPLOYEES
和 L_TBL_EMPLOYEE
简单明了,采用这样的命名约定将使调试代码变得无比容易。