ヘッダーをスキップ
Oracle® Database PL/SQL言語リファレンス
11gリリース2 (11.2)
B56260-09
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

CREATE PACKAGE BODY文

CREATE PACKAGE BODY文は、データベースに1つの単位として格納される、関連するプロシージャやストアド・ファンクション、その他のプログラム・オブジェクトをカプセル化したコレクションである、ストアド・パッケージの本体を作成するか、または置き換えます。パッケージ本体でこれらのオブジェクトを定義します。前述のCREATE PACKAGE文で定義したパッケージ仕様部で、これらのオブジェクトを宣言します。

パッケージは、プロシージャおよびファンクションをスタンドアロン・スキーマ・オブジェクトとして作成する場合の代替方法です。

ここでのトピック

前提条件

自分のスキーマ内にパッケージを作成するか、または自分のスキーマ内のパッケージを置き換えるには、CREATE PROCEDUREシステム権限が必要です。別のユーザーのスキーマ内にパッケージを作成するか、または別のユーザーのスキーマ内のパッケージを置き換えるには、CREATE ANY PROCEDUREシステム権限が必要です。いずれの場合も、パッケージ本体をパッケージと同じスキーマに作成する必要があります。

CREATE PACKAGE BODY文をデータベースのプリコンパイラ・プログラム内に埋め込むには、キーワードEND-EXECの後に特定の言語の埋込みSQL文の終了記号を付けて文を終了する必要があります。

セマンティクス

OR REPLACE

パッケージ本体が存在する場合は、パッケージ本体を再作成し、再コンパイルします。

再定義する前のパッケージ本体に対する権限を付与されていたユーザーは、権限を再付与される必要なく、パッケージにアクセスできます。

schema

パッケージが含まれているスキーマの名前。デフォルト: 自分のスキーマ。

package_name

作成するパッケージの名前。

declare_section

パッケージ仕様部のすべてのカーソル定義およびサブプログラム宣言を配置します。対応するサブプログラム宣言と定義のヘッダーは、空白以外の一語一語が一致している必要があります。

パッケージ内からのみ参照できるプライベート項目を宣言および定義することもできます。

declare_sectionの制限 ここではAUTONOMOUS_TRANSACTIONプラグマを使用できません。

initialize_section

変数を初期化し、その他の1回のみの設定手順をすべて実行します。

パッケージ本体の作成: 例 次の文は、「パッケージの作成: 例」で作成した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@example.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_empremove_deptincrease_salおよびincrease_comm

これらのオブジェクトはパッケージ仕様部で宣言されているため、パッケージ外部のアプリケーション・プログラム、プロシージャおよびファンクションでコールできます。たとえば、パッケージにアクセスできる場合は、increase_commプロシージャを起動するemp_mgmtパッケージとは別にプロシージャincrease_all_commsを作成できます。

これらのオブジェクトはパッケージ本体で定義されているため、依存するスキーマ・オブジェクトをデータベースで無効にしなくても、オブジェクトの定義を変更できます。たとえば、この後にhireの定義を変更した場合、データベースで実行する前にincrease_all_commsを再コンパイルする必要はありません。

また、この例のパッケージ本体では、プライベート・プログラム・オブジェクトである変数tot_empsおよびtot_deptsも宣言しています。これらのオブジェクトは、パッケージ仕様部ではなくパッケージ本体で宣言されているため、パッケージ内の他のオブジェクトからはアクセスできますが、パッケージの外部からはアクセスできません。たとえば、変数tot_deptsの値を明示的に変更するアプリケーションを開発することはできません。ただし、ファンクションcreate_deptはパッケージの一部であるため、create_depttot_deptsの値を変更できます。