2

これはパッケージ仕様です:

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: この式の型の宣言が不完全であるか、形式が正しくありません。

誰かがこれで私を助けてくれますか?

4

2 に答える 2

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>

必要な出力があります。

于 2015-03-23T06:01:26.397 に答える
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();
于 2015-03-23T04:58:41.397 に答える