CREATE
PACKAGE
BODY
文は、ストアド・パッケージの本体を作成するか、または置き換えます。ストアド・パッケージとは、データベースにまとめて格納される関連するプロシージャやストアド・ファンクションなどのプログラム・オブジェクトをカプセル化したコレクションです。 パッケージ本体で、これらのオブジェクトを定義します。 前述のCREATE
PACKAGE
文で定義したパッケージ仕様部で、これらのオブジェクトを宣言します。
パッケージは、プロシージャおよびファンクションをスタンドアロン・スキーマ・オブジェクトとして作成する場合の代替方法です。
前提条件
自身のスキーマ内にパッケージを作成するか、または自身のスキーマ内のパッケージを置き換えるには、CREATE
PROCEDURE
システム権限が必要です。 別のユーザーのスキーマ内にパッケージを作成するか、または別のユーザーのスキーマ内のパッケージを置き換えるには、CREATE
ANY
PROCEDURE
システム権限が必要です。 いずれの場合も、パッケージ本体をパッケージと同じスキーマに作成する必要があります。
CREATE
PACKAGE
BODY
文をデータベースのプリコンパイラ・プログラム内に埋め込むには、キーワードEND-EXEC
の後に特定の言語の埋込みSQL文の終了記号を付けて文を終了する必要があります。
構文
create_package_body ::=
(declare_section ::=、body ::=)
キーワードとパラメータの説明
OR
REPLACE
を指定すると、パッケージ本体がすでに存在する場合に再作成できます。 この句を使用すると、既存のパッケージに以前に付与されたオブジェクト権限を削除、再作成および再付与しなくても、そのパッケージの本体を変更できます。 パッケージ本体を変更すると、パッケージ本体はデータベースによって再コンパイルされます。
再定義されたパッケージに対する権限を以前に付与されているユーザーは、権限を再付与される必要なく、パッケージにアクセスできます。
schema
パッケージを含めるスキーマを指定します。 schema
を省略すると、データベースによって現行のスキーマにパッケージが作成されます。
package_name
作成するパッケージの名前を指定します。
declare_section
パッケージ・オブジェクトを宣言します。
body
パッケージ・オブジェクトを定義します。
例
パッケージ本体の作成: 例 次の文は、「パッケージの作成: 例」で作成したemp_mgmt
パッケージの本体を作成します。
CREATE OR REPLACE PACKAGE BODY emp_mgmt AS
tot_emps NUMBER;
tot_depts NUMBER;
FUNCTION hire
(last_name VARCHAR2, job_id VARCHAR2,
manager_id NUMBER, salary NUMBER,
commission_pct NUMBER, department_id NUMBER)
RETURN NUMBER IS new_empno NUMBER;
BEGIN
SELECT employees_seq.NEXTVAL
INTO new_empno
FROM DUAL;
INSERT INTO employees
VALUES (new_empno, 'First', 'Last','first.example@oracle.com',
'(415)555-0100','18-JUN-02','IT_PROG',90000000,00,
100,110);
tot_emps := tot_emps + 1;
RETURN(new_empno);
END;
FUNCTION create_dept(department_id NUMBER, location_id NUMBER)
RETURN NUMBER IS
new_deptno NUMBER;
BEGIN
SELECT departments_seq.NEXTVAL
INTO new_deptno
FROM dual;
INSERT INTO departments
VALUES (new_deptno, 'department name', 100, 1700);
tot_depts := tot_depts + 1;
RETURN(new_deptno);
END;
PROCEDURE remove_emp (employee_id NUMBER) IS
BEGIN
DELETE FROM employees
WHERE employees.employee_id = remove_emp.employee_id;
tot_emps := tot_emps - 1;
END;
PROCEDURE remove_dept(department_id NUMBER) IS
BEGIN
DELETE FROM departments
WHERE departments.department_id = remove_dept.department_id;
tot_depts := tot_depts - 1;
SELECT COUNT(*) INTO tot_emps FROM employees;
END;
PROCEDURE increase_sal(employee_id NUMBER, salary_incr NUMBER) IS
curr_sal NUMBER;
BEGIN
SELECT salary INTO curr_sal FROM employees
WHERE employees.employee_id = increase_sal.employee_id;
IF curr_sal IS NULL
THEN RAISE no_sal;
ELSE
UPDATE employees
SET salary = salary + salary_incr
WHERE employee_id = employee_id;
END IF;
END;
PROCEDURE increase_comm(employee_id NUMBER, comm_incr NUMBER) IS
curr_comm NUMBER;
BEGIN
SELECT commission_pct
INTO curr_comm
FROM employees
WHERE employees.employee_id = increase_comm.employee_id;
IF curr_comm IS NULL
THEN RAISE no_comm;
ELSE
UPDATE employees
SET commission_pct = commission_pct + comm_incr;
END IF;
END;
END emp_mgmt;
/
パッケージ本体では、パッケージ仕様部で宣言された次のパブリック・プログラム・オブジェクトを定義します。
ファンクションhire
およびcreate_dept
プロシージャremove_emp
、remove_dept
、increase_sal
およびincrease_comm
これらのオブジェクトはパッケージ仕様部で宣言されているため、パッケージ外部のアプリケーション・プログラム、プロシージャおよびファンクションでコールできます。 たとえば、パッケージにアクセスできる場合は、increase_comm
プロシージャをコールするemp_mgmt
パッケージとは別にプロシージャincrease_all_comms
を作成できます。
これらのオブジェクトはパッケージ本体で定義されているため、依存するスキーマ・オブジェクトをデータベースで無効にしなくても、オブジェクトの定義を変更できます。 たとえば、この後にhire
の定義を変更した場合、データベースで実行する前にincrease_all_comms
を再コンパイルする必要はありません。
また、この例のパッケージ本体では、プライベート・プログラム・オブジェクトである変数tot_emps
およびtot_depts
も宣言しています。 これらのオブジェクトは、パッケージ仕様部ではなくパッケージ本体で宣言されているため、パッケージ内の他のオブジェクトからはアクセスできますが、パッケージの外部からはアクセスできません。 たとえば、変数tot_depts
の値を明示的に変更するアプリケーションを開発することはできません。 ただし、ファンクションcreate_dept
はパッケージの一部であるため、create_dept
でtot_depts
の値を変更できます。
関連トピック