パッケージ本体

パッケージ仕様部でカーソルまたはサブプログラムを宣言している場合は、パッケージ本体が必要ですが、それ以外の場合、本体はオプションです。パッケージ本体とパッケージ仕様部は同じスキーマ内にある必要があります。

パッケージ仕様部内のカーソル宣言またはサブプログラム宣言の1つ1つに対応する定義がパッケージ本体にある必要があります。対応するサブプログラム宣言と定義のヘッダーは、空白以外の一語一語が一致している必要があります。

パッケージ本体を作成するには、「 CREATE PACKAGE BODY文」を使用します。

パッケージ仕様部で宣言し、パッケージ本体で定義したカーソルおよびサブプログラムは、パッケージの外から参照できるパブリック項目です。パッケージ本体では、パッケージの外からは参照できなくてもパッケージの内部動作に必要なプライベート項目を宣言および定義することもできます。

本体の最後には初期化部を配置することができ、ここには、パブリック変数を初期化する文と、その他の1回のみの設定ステップを実行する文を入れます。初期化部は、パッケージが初めて参照されたときにのみ実行されます。初期化部には例外ハンドラを含めることができます。

パッケージ本体は、仕様部またはパブリック項目への参照を変更せずに変更できます。

例11-3 パッケージの仕様部と本体の一致

この例では、対応するサブプログラム宣言と定義のヘッダーが完全一致していません。そのため、employees.hire_date%TYPEDATEであっても、PL/SQLによって例外が生成されます。

CREATE PACKAGE emp_bonus AS
  PROCEDURE calc_bonus (date_hired employees.hire_date%TYPE);
END emp_bonus;
/
CREATE PACKAGE BODY emp_bonus AS
  -- DATE does not match employees.hire_date%TYPE
  PROCEDURE calc_bonus (date_hired DATE) IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE
      ('Employees hired on ' || date_hired || ' get bonus.');
  END;
END emp_bonus;
/

結果:

Warning: Package Body created with compilation errors.

SQL*Plusでのエラーの表示:

SHOW ERRORS

結果:

Errors for PACKAGE BODY EMP_BONUS:
 
LINE/COL ERROR
-------- -----------------------------------------------------------------
2/13     PLS-00323: subprogram or cursor 'CALC_BONUS' is declared in a
         package specification and must be defined in the package body

問題の修正:

CREATE OR REPLACE PACKAGE BODY emp_bonus AS
  PROCEDURE calc_bonus
    (date_hired employees.hire_date%TYPE) IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE
      ('Employees hired on ' || date_hired || ' get bonus.');
  END;
END emp_bonus;
/

結果:

Package body created.