Oracle PACKAGEの作成
オラクルには パッケージ と呼ばれるオブジェクトがあります。
この パッケージ はPL/SQLの型、変数、定数、PROCEDURE、FUNCTIONなどをひとまとめにしたものです。
オラクル社が提供するPL/SQLパッケージには多くのものがあり、私も一度は使用した簡単なものとして DBMS_OUTPUT パッケージがあります。
この DBMS_OUTPUT には単にコンソール画面に文字列を出力する PUT_LINE 関数がありますが、これを使用する例を示します。
尚、パッケージの中の関数をコールする場合は「パッケージ名.関数名」とドットで連結します。
SQL> SET SERVEROUTPUT ON; SQL> BEGIN 2 DBMS_OUTPUT.PUT_LINE('TEST 出力...'); 3 END; 4 / TEST 出力... PL/SQLプロシージャが正常に完了しました。
特に問題無く「TEST 出力...」の文字列が表示されます。
尚、コンソール画面に表示されない場合は上の様に「SET SERVEROUTPUT ON」を行います。
それでは パッケージ について順次説明していきます。
おすすめ書籍
- 図解入門よくわかる最新Oracleデータベースの基本と仕組み[第4版] (How‐nual Visual Guide Book)
- Oracleの基本 ~データベース入門から設計/運用の初歩まで
- [改訂第4版]SQLポケットリファレンス
パッケージの作成構文
パッケージは「仕様部」と「本体」から構成します。「仕様部」は必ず宣言しパッケージの外から参照できるパブリック項目を宣言します。
「仕様部」はAPI(Application Programming Interface)と考えることができます。
「本体」には、パブリック・カーソルの問合せとパブリック・サブプログラムのコードを定義します。
「本体」では、パッケージ内部のみ参照可能なプライベート項目を宣言および定義することもできます。
「本体」は、「仕様部」を変更せずに変更できるため、インターフェースはそのままで内部処理を変更できます。
-- パッケージ「仕様部」 CREATE [OR REPLACE] PACKAGE [<スキーマ名>.]<パッケージ名> AS {複数のプロシージャ定義} ... {複数のファンクション定義} ... {複数の変数定義} ... END [<スキーマ名>.]<パッケージ名>; -- パッケージ「本体」 CREATE [OR REPLACE] PACKAGE BODY [<スキーマ名>.]<パッケージ名> IS {複数のプロシージャ宣言(仕様部の同じプロシージャ名で宣言)} ... {複数のファンクション宣言(仕様部の同じファンクション名で宣言)} ... {複数の変数宣言} ... END [<スキーマ名>.]<パッケージ名>;
スキーマ名 はいわゆるユーザ名のことで省略すれば現在ログインしているスキーマにパッケージは作成されます。
但し、前提条件としてログインスキーマに対してパッケージの作成権限が与えられていないとこのCREATE文は失敗します。
尚、[OR REPLACE] はパッケージを上書き登録する場合に指定します。
「本体」の「プロシージャ宣言」「ファンクション宣言」は「仕様部」での定義と同じ名前・引数でなければなりません。
簡単なパッケージの作成と実行1(PROCEDURE, FUNCTION宣言のみ)
SQL> -- パッケージ「仕様部」 SQL> CREATE OR REPLACE PACKAGE PKG_TEST AS 2 PROCEDURE PROC1(data1 IN VARCHAR2, data2 OUT VARCHAR2); 3 FUNCTION FUNC1(data1 IN VARCHAR2) RETURN VARCHAR2; 4 END PKG_TEST; 5 / パッケージが作成されました。 SQL> -- パッケージ「本体」 SQL> CREATE OR REPLACE PACKAGE BODY PKG_TEST IS 2 -- プロシージャ宣言 3 PROCEDURE PROC1(data1 IN VARCHAR2, data2 OUT VARCHAR2) 4 IS 5 BEGIN 6 data2 := 'PROC1...' || data1; 7 DBMS_OUTPUT.PUT_LINE(data2); 8 END PROC1; 9 10 -- ファンクション宣言 11 FUNCTION FUNC1(data1 IN VARCHAR2) RETURN VARCHAR2 12 IS 13 BEGIN 14 RETURN 'FUNC1***' || data1; 15 END FUNC1; 16 END PKG_TEST; 17 / パッケージ本体が作成されました。
「本体」の PROC1 は VARCHAR2 型の引数を2個受け取り、2番目の引数に文字列を付加し、コンソールに表示して返す簡単なプロシージャです。
「本体」の FUNC1 は VARCHAR2 型の引数を受け取り、文字列を付加したものを返す簡単なファンクションです。
これらのパッケージのプロシージャ、ファンクションを使用する例を以下に示します。
SQL> DECLARE 2 D1 VARCHAR2(256); 3 BEGIN 4 -- プロシージャCALL 5 PKG_TEST.PROC1('TEST1', D1); 6 DBMS_OUTPUT.PUT_LINE('#' || D1); 7 -- ファンクションCALL 8 D1 := PKG_TEST.FUNC1('TEST2'); 9 DBMS_OUTPUT.PUT_LINE(D1); 10 END; 11 / PROC1...TEST1 #PROC1...TEST1 FUNC1***TEST2 PL/SQLプロシージャが正常に完了しました。
簡単なパッケージの作成と実行2(パブリック変数宣言・使用)
パブリック変数宣言を「仕様部」に行い「本体」のプロシージャ、ファンクションから使用する例を以下に示します。
この例ではプロシージャ、ファンクション内で処理した文字列をそれぞれ退避する変数に入れています。
SQL> -- パッケージ「仕様部」 SQL> CREATE OR REPLACE PACKAGE PKG_TEST AS 2 PROCEDURE PROC1(data1 IN VARCHAR2, data2 OUT VARCHAR2); 3 FUNCTION FUNC1(data1 IN VARCHAR2) RETURN VARCHAR2; 4 -- パブリック変数宣言 5 LAST_PROC1_STR VARCHAR2(256); 6 LAST_FUNC1_STR VARCHAR2(256); 7 END PKG_TEST; 8 / パッケージが作成されました。 SQL> -- パッケージ「本体」 SQL> CREATE OR REPLACE PACKAGE BODY PKG_TEST IS 2 -- プロシージャ宣言 3 PROCEDURE PROC1(data1 IN VARCHAR2, data2 OUT VARCHAR2) 4 IS 5 BEGIN 6 data2 := 'PROC1...' || data1; 7 DBMS_OUTPUT.PUT_LINE(data2); 8 -- パブリック変数に退避 9 LAST_PROC1_STR := data2; 10 END PROC1; 11 12 -- ファンクション宣言 13 FUNCTION FUNC1(data1 IN VARCHAR2) RETURN VARCHAR2 14 IS 15 DSTR VARCHAR2(256); 16 BEGIN 17 DSTR := 'FUNC1***' || data1; 18 -- パブリック変数に退避 19 LAST_FUNC1_STR := DSTR; 20 RETURN DSTR; 21 END FUNC1; 22 END PKG_TEST; 23 / パッケージ本体が作成されました。
このパッケージのプロシージャ、ファンクションを使用する例を以下に示します。
SQL> DECLARE 2 D1 VARCHAR2(256); 3 BEGIN 4 -- プロシージャCALL 5 PKG_TEST.PROC1('TEST1', D1); 6 DBMS_OUTPUT.PUT_LINE('#' || PKG_TEST.LAST_PROC1_STR); 7 -- ファンクションCALL 8 D1 := PKG_TEST.FUNC1('TEST2'); 9 DBMS_OUTPUT.PUT_LINE('#' || PKG_TEST.LAST_FUNC1_STR); 10 END; 11 / PROC1...TEST1 #PROC1...TEST1 #FUNC1***TEST2 PL/SQLプロシージャが正常に完了しました。 SQL> BEGIN 2 DBMS_OUTPUT.PUT_LINE('!' || PKG_TEST.LAST_FUNC1_STR); 3 END; 4 / !FUNC1***TEST2 PL/SQLプロシージャが正常に完了しました。
パッケージの中のパブリック変数にはプロシージャ、ファンクションの呼出時に、値が設定されることが分かります。
また、2個めのPL/SQLプロシージャでは再度、パブリック変数をアクセスしていますが、最後の値が残っていることが分かります。
このパッケージのインスタンスは、ログインのセッション毎に別に作られる様で、もう1個「SQLPlus」を立ち上げて最後のPL/SQLプロシージャを実行しても
パブリック変数はNULLの様です。
SQL> SET SERVEROUTPUT ON; SQL> BEGIN 2 DBMS_OUTPUT.PUT_LINE('!' || PKG_TEST.LAST_FUNC1_STR); 3 END; 4 / ! PL/SQLプロシージャが正常に完了しました。