这是包规范:
create or replace PACKAGE EMPLOYEE_DETAILS AS
TYPE DETAILS IS RECORD(
EMPLOYEE_ID NUMBER(6,0),
EMPLOYEE_FIRST_NAME VARCHAR2(20),
EMPLOYEE_LAST_NAME VARCHAR2(25)
);
TYPE TABLE_EMPLOYEES IS TABLE OF DETAILS;
PROCEDURE GET_EMPLOYEES(
EMP_DEPT_ID EMPLOYEES.DEPARTMENT_ID%TYPE,
EMP_SALARY employees.salary%TYPE,
TBL_EMPLOYEES OUT TABLE_EMPLOYEES
);
END EMPLOYEE_DETAILS;
这是包体。我能够编译包,但需要一些帮助来执行存储过程来验证结果。
create or replace PACKAGE BODY EMPLOYEE_DETAILS AS
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;
END EMPLOYEE_DETAILS;
到目前为止我所拥有的是:
set serveroutput on
declare
tbl_employees table_employees;
begin
employee_details.get_employees(30,1000,tbl_employees);
For i IN tbl_employees.First .. tbl_employees.Last Loop
dbms_output.put_line(tbl_employees(i).employee_id || ' ' ||
tbl_employees(i).first_name|| ' ' ||
tbl_employees(i).last_name);
End Loop;
end;
但是当我执行此操作时,它会给我一个错误说
必须声明
table_employees
另一个是
PLS-00320:此表达式类型的声明不完整或格式错误。
有人可以帮帮我吗?
答案 0 :(得分:6)
您正在错误地引用记录类型。
tbl_employees table_employees;
必须声明table_employees
您使用的是记录类型,而不是对象类型。因此,您不能将记录类型称为数据库对象。您需要将其称为您创建的包对象。
您需要将记录类型称为:
<强> l_table_rec_type employee_details.table_employees
强>
让我们看一个完整的测试用例:
SQL> CREATE OR REPLACE
2 PACKAGE employee_details
3 AS
4 TYPE details
5 IS
6 RECORD
7 (
8 p_name VARCHAR2(40),
9 p_emp_id NUMBER );
10 TYPE table_employees
11 IS
12 TABLE OF details;
13 PROCEDURE get_employees(
14 p_deptno IN emp.deptno%TYPE,
15 p_sal IN emp.sal%TYPE,
16 emp_rec OUT table_employees );
17 END employee_details;
18 /
Package created.
SQL>
创建了包
SQL> CREATE OR REPLACE
2 PACKAGE BODY employee_details
3 AS
4 PROCEDURE get_employees(
5 p_deptno IN emp.deptno%TYPE,
6 p_sal IN emp.sal%TYPE,
7 emp_rec OUT table_employees )
8 IS
9 BEGIN
10 SELECT ename, empno BULK COLLECT INTO emp_rec FROM scott.emp where deptno = p_deptno and sal > p_sal;
11 END get_employees;
12 END employee_details ;
13 /
Package body created.
SQL>
还会创建包体。现在让我们来调用这个程序。
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2 l_table_rec_type employee_details.table_employees;
3 BEGIN
4 dbms_output.put_line(' calling get_employees ');
5 employee_details.get_employees(30, 1000, l_table_rec_type);
6 FOR l_rec IN 1..l_table_rec_type.count
7 LOOP
8 dbms_output.put_line('employee details ' || l_table_rec_type(l_rec).p_name ||' '||l_table_rec_type(l_rec).p_emp_id);
9 END LOOP;
10 END;
11 /
calling get_employees
employee details ALLEN 7499
employee details WARD 7521
employee details MARTIN 7654
employee details BLAKE 7698
employee details TURNER 7844
PL/SQL procedure successfully completed.
SQL>
您有所需的输出。
答案 1 :(得分:1)
由于table_employees是在包employee_details中定义的,因此请使用
tbl_employees employee_details.table_employees := employee_details.table_employees();
也可以在包体中初始化集合进行相同的更改
create or replace PACKAGE BODY EMPLOYEE_DETAILS AS
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:= table_employees();