【PL/SQL】パッケージの書き方(作成/実行/呼び出し/削除)

ここではORACLE社が提供するPL/SQL言語でパッケージの書き方(作成/実行/呼び出し/削除)を紹介しています。

PL/SQLで実行できる処理は↓でまとめて紹介していますので参考にしてください。
>>PL/SQLの処理

パッケージとは

パッケージとは、プロシージャやファンクションをまとめてカプセル化したものです。

パッケージは、事前に処理を定義しておき、呼び出して使います。

DBMSパッケージなど、ORACLEデータベースで事前定義されているものがあります。また、自分で定義・作成することも出来ます。

CREATE文:パッケージの作成・登録方法

パッケージは仕様部と本体の2つで構成されています。仕様部はCREATE PACKAGE、本体はCREATE PACKAGE BODY文で作成します。

パッケージの仕様部は、パッケージに含まれるプロシージャやファンクションの宣言部分(名前・引数・戻り値)を記述します。

パッケージ本体では、パッケージで定義する変数、パッケージに含まれるプロシージャやファンクションの具体的な処理内容を記述します。

仕様部の書き方

CREATE [OR REPLACE] PACKAGE パッケージ名 AS
    /* パッケージに含むプロシージャ */
    PROCEDURE プロシージャ名 [(引数名 {IN | OUT | IN OUT } データ型,..)];

    /* パッケージに含むファンクション */
    FUNCTION ファンクション名 [(引数名 {IN | OUT | IN OUT } データ型,..)]
    RETURN 戻り値のデータ型;
END;
/

・OR REPLACE
 同じ名前のパッケージが存在する場合、上書き更新します。

・IN
 プロシージャやファンクションの引数として値を受け取るだけの変数の宣言します。

・OUT
 プロシージャやファンクションの結果として値を格納する変数の宣言します。

・IN OUT
 IN,OUT、両方の特性を持ちます。
 プロシージャやファンクションの引数としても使え、処理の結果で上書きし返すことが出来ます。

本体の書き方

CREATE [OR REPLACE] PACKAGE BODY パッケージ名 AS
    /* パッケージに含むプロシージャ */
    PROCEDURE プロシージャ名 (引数)
    IS
        /* 宣言部 */
    BEGIN
        /* 処理部 */
    END;

     /* パッケージに含むファンクション */
    FUNCTION ファンクション名(引数) RETURN 戻り値のデータ型
    IS
       /* 宣言部 */
    BEGIN
       /* 処理部 */
       RETURN 戻り値;
    END;
END;
/

・宣言部
 プロシージャやファンクション内で使用する変数を宣言します。

・処理部
 プロシージャやファンクション内の処理をコーディングします。

・EXCEPTION
 プロシージャやファンクション内で発生したエラーに対する処理を記述します。

パッケージのサンプルプログラム

仕様部はCREATE PACKAGE文、本体はCREATE PACKAGE BODY文で作成します。

プロシージャやファンクションの書き方については↓で詳しく解説しているので参考にしてください。
>>プロシージャの書き方(作成/実行/呼び出し/削除)
>>ファンクションの書き方(作成/実行/呼び出し/削除)

仕様部のサンプルプログラム

パッケージの仕様部では、プロシージャやファンクションの名前と引数、戻り値のデータ型を書きます。

ここではプロシージャ、ファンクションでそれぞれ引数のあるものと引数なしのものを定義しています。

CREATE OR REPLACE PACKAGE pkg1 AS
    /* パッケージに含むプロシージャ1 */
    PROCEDURE proc1(p1 IN NUMBER,p2 OUT NUMBER);

    /* パッケージに含むプロシージャ2 */
    PROCEDURE proc2;

    /* パッケージに含むファンクション1 */
    FUNCTION func1(p1 IN NUMBER,p2 IN NUMBER) RETURN NUMBER;

    /* パッケージに含むファンクション2 */
    FUNCTION func2 RETURN VARCHAR2;
END;
/

本体のサンプルプログラム

パッケージの本体では、プロシージャやファンクションの具体的な処理内容を書きます。

ここでは簡単な計算処理やDBMSパッケージを使ったメッセージの出力、文字列の返却を行っています。

CREATE OR REPLACE PACKAGE BODY pkg1 AS
    /* パッケージに含むプロシージャ1 */
    PROCEDURE proc1(p1 IN NUMBER,p2 OUT NUMBER)
    IS
    BEGIN
        p2 := p1 * 5;
    END;

    /* パッケージに含むプロシージャ2 */
    PROCEDURE proc2
    IS
    BEGIN
        DBMS_OUTPUT.PUT_LINE('test');
    END;

    /* パッケージに含むファンクション1 */
    FUNCTION func1(p1 IN NUMBER,p2 IN NUMBER) RETURN NUMBER
    IS
    BEGIN
        RETURN p1 + p2;
    END;

    /* パッケージに含むファンクション2 */
    FUNCTION func2 RETURN VARCHAR2
    IS
    BEGIN
        RETURN 'test';
    END;
END;
/

パッケージの実行・呼び出し

EXECUTE文を使うことで、パッケージ内のプロシージャやファンクションを実行することが出来ます。

EXECUTEコマンドでは「パッケージ名.プロシージャ名」または「パッケージ名.ファンクション名」として実行します。

EXECUTE文はEXECと省略することも出来ます。

EXECUTE パッケージ名.プロシージャ名[(引数)];

または

EXECUTE パッケージ名.ファンクション名[(引数)];

パッケージ内のプロシージャの実行・呼び出し

パッケージ内のプロシージャは「パッケージ名.プロシージャ名」で実行します。

まず「variable 変数名 データ型;」で変数を宣言して、IN引数にパラメータを渡しています。「EXECUTE :変数名 := 値;」で変数に値を代入することが出きます。

「EXECUTE pkg1.proc1(:p1,:p2);」で、pkg1パッケージのproc1プロシージャを実行しています。

「print :変数名;」でOUT変数の内容を確認しています。

SQL> variable p1 NUMBER;
SQL> variable p2 NUMBER;
SQL> EXECUTE :p1 := 5;

PL/SQLプロシージャが正常に完了しました。

SQL> EXECUTE pkg1.proc1(:p1,:p2);

PL/SQLプロシージャが正常に完了しました。

SQL> print :p2;

        P2
----------
        25

引数なしのプロシージャproc2も同様に呼び出しています。

引数なしの場合は「EXECUTE パッケージ名.プロシージャ名」だけになります。

ここでは「set serveroutput on;」でSQLPLUSでDBMSパッケージによる画面への出力をONにしています。

SQL> set serveroutput on;
SQL> EXECUTE pkg1.proc2;
test

PL/SQLプロシージャが正常に完了しました。

パッケージ内のファンクションの実行・呼び出し

パッケージ内のファンクションは「パッケージ名.ファンクション名」で実行します。

まず「variable 変数名 データ型;」で変数を宣言して、IN引数にパラメータを渡しています。「EXECUTE :変数名 := 値;」で変数に値を代入することが出きます。

ファンクションの戻り値・結果を格納するための変数を「variable result NUMBER;」で宣言しています。

「EXECUTE :result := pkg1.func1(:p1,:p2);」で、pkg1パッケージのfunc1ファンクションを実行しています。

「print :変数名;」で処理の結果を確認しています。

SQL> variable p1 NUMBER;
SQL> variable p2 NUMBER;
SQL> variable result NUMBER;
SQL> EXECUTE :p1 := 5;

PL/SQLプロシージャが正常に完了しました。

SQL> EXECUTE :p2 := 5;

PL/SQLプロシージャが正常に完了しました。

SQL> EXECUTE :result := pkg1.func1(:p1,:p2);

PL/SQLプロシージャが正常に完了しました。

SQL> print :result;

    RESULT
----------
        10

引数なしのファンクションは「パッケージ名.ファンクション名」のみで「(引数)」の記述なしで実行します。

SQL> variable result VARCHAR2(10);
SQL> EXECUTE :result := pkg1.func2;

PL/SQLプロシージャが正常に完了しました。

SQL> print :result;

RESULT
----------------------------------------------------------------
test

また、OUT引数のないファンクションはSQL内でも利用することが出来ます。

SQL> SELECT pkg1.func2 FROM dual;

FUNC2
--------------------------------------------------------------------------------
test

パッケージの削除

パッケージの削除には、DROP PACKAGE文を使います。

DROP PACKAGE パッケージ名; 

実行すると次のように結果を返します。

SQL> DROP PACKAGE pkg1;

パッケージが削除されました。

パッケージの作成に必要な権限

パッケージの作成や実行にはCREATE権限やEXECUTE権限が必要です。

必要な権限については↓でまとめていますので参考にしてください。
>>作成や実行に必要な権限と確認・付与する方法

>>【ORACLE】システム権限を付与・取消するSQL