e-learning、オラクル研修、LMS(学習管理システム)のiStudy

e-learning、オラクル研修、LMS(学習管理システム)のiStudy

第30回 「パッケージでできること 変数の永続性」

2012.07.30

前回は、PL/SQLを使うことで、パラメータなどが違えば、同じ名前のサブプログラム(プロシージャ、ファンクション)が作成できることをご紹介しました。
これをオーバーロードといいます。

今回もPL/SQLのパッケージを使うことで可能性となる機能をご紹介します。

それは「パッケージ変数の永続性」という機能です。
一言でいえば、パッケージで宣言した変数はセッションの間、値を保持し続けることです。

例えば、以下のようにPAC1パッケージの仕様部にAという変数を宣言します。

CREATE OR REPLACE PACKAGE PAC1 IS
   A NUMBER;
END;

この変数AはPAC1パッケージの仕様部で宣言していますので、ユーザーや外部のアプリケーションからPAC1.Aと記述して参照できます。
したがって、次のような無名PL/SQLブロックで、このPAC1パッケージのA変数に、10という値を代入しました。

BEGIN
   PAC1.A := 10;
END;

そうすると、この無名PL/SQLブロックの実行が終わっても、このPAC1.A変数は、セッションが終わるまでずっと残っているのです。
したがって、次に以下のような無名PL/SQLブロックをSQL*Plusなどから実行すると、PAC1.A の値、すなわち「10」が表示されます。
(ここで、これらの処理を行ったセッションを、セッション1と呼ぶことにします)

BEGIN
   DBMS_OUTPUT.PUT_LINE(PAC1.A);
END;

上のブロックを実行する場合、「SET SERVEROUTOUT ON」で画面表示可能にしてから実行してください。
すると、「10」という値がSQL*PlusまたはSQL*Developerで表示されますね。
つまり、無名PL/SQLブロックの実行が終わっても、PAC1.Aは残っており、値10を保持していることがわかります。

このとき、別のセッションで(ここではそのセッションをセッション2と呼びます)、PAC1.Aに20という値を代入したとします。
しかしこのことはセッション1にはなんら影響しません。
セッション1から見るとPAC1.A変数はあくまでも10という値を保持してます。
しかし、セッション2から見るとPAC1.A変数は20を保持しているのです。

つまりパッケージ変数は、同じパッケージの同じ名前の変数でも、セッション毎に存在し、セッションが終わるまで値を保持するのです。

通常、変数はPL/SQLのブロック内の宣言部で宣言し、そのブロックの実行が終わればその変数もメモリから消えます。
しかし、パッケージに宣言された変数は一旦そのパッケージが使われたら、それを使ったPL/SQLブロックが終了しても、セッションが終わるまでメモリに残って値を保持しているのです。

このことを利用すれば、様々な用途が考えられます。
「どんな用途?」と聞かれても一言でいえないくらい様々な用途が考えられますよ。
例えば、あるプロシージャで処理した結果を一旦、パッケージの変数に格納しておいて、後で、別プロシージャがその変数を参照しながらなにかの処理を行うとか・・・。
あるいは、まだご紹介してませんがデータベーストリガーというプログラムがあります。
このトリガーというものは、一般に特定の表に対して更新処理を行うときにバックグラウンドで自動的に起動してなにかの処理を行うプログラムです。
このデータベーストリガーは、プロシージャやファンクションと違って、パラメータというものを持っていません。
従って、トリガーに何かの値を渡したい場合、パッケージの変数を使うという方法があります。
その話はまた別の機会で触れたいと思います。

いずれにしろ、パッケージに格納された変数は、セッションの継続中値を保持します。
それを使って何をするかについては、アイディア次第なのです。

逆に、セッションの間、変数が保持されることを期待しない場合もあるかもしれません。
パッケージの変数がセッションの間、残る必要はない、残ってもらってもメモリの無駄となるだけ、という場合もあるかもしれません。そういった場合はキーワードだけ紹介しますが、「PRAGMA SERIALLY_REUSABLE」という指定で可能です。
その変数を使ったPL/SQLブロックの実行が終われば、その変数も消えます。
しかしそういった特段の指定をしない限りはパッケージの変数はセッションが終わるまで保持されます。

それでは、今回はここまでです。また次回ご期待下さい。

先頭へ戻る