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

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

第67回 「複合トリガー(その1)」(2013.07.29)

2013.07.29

こんにちは。インストラクターの蓑島です。暑い日が続きますね。
夏バテ気味が少し解消してきたのですが、暑さはまだまだ続きます。涼しい秋が待ち遠しいものです。

さて、今回から次回にかけて、新しいテーマ「複合トリガー」をご紹介します。

トリガーについては、バックナンバー第36回~42回にかけて紹介済みですが、覚えていますか?
トリガーとは、何かのイベントが発生したときに、自動的に起動されるPL/SQLのプログラムでしたね。
イベントの種類により様々なトリガーがあるのですが、一般的には、データベースの表に対して、DML文(INSERT, UPDATE, DELETE)が実行されるときに自動起動されるトリガーが代表的なものです。

そのような、表に対するDMLトリガーは次の4種類に分類できます。

・BEFOREの文トリガー
・BEFREEの行トリガー
・AFTERの行トリガー
・AFTERの文トリガー

「BEFORE」、「AFTER」の意味は、起動タイミングが、DML操作の「前」か「後」かということです。
また、「文」トリガーについては、文ごとのトリガーということであり、DML文が処理する行数に関係なく1回だけ起動します。「行」トリガーについては行ごとのトリガーということであり、DMLが処理するそれぞれの行ごとにその行の上で起動するトリガーです。
特に行トリガーでは、その行の上で動いているので、その行の列の値を参照できるとことがポイントでしたね。

では、今回新しく紹介する「複合トリガー」とは、どのようなものかというと、上の4種類のトリガーを一つのトリガーにまとめたものということができます。

簡単にいうと、「複合トリガー」には4つのセクションがあり、それぞれのセクションが「BEFOREの文トリガー」、「AFTERの文トリガー」、「BEFREEの行トリガー」、「AFTERの行トリガー」に相当しているのです。

このように「複合トリガー」とは、上記の4種類のトリガーを一つにまとめたものといえます。しかし、それだけではありません。

「複合トリガー」には、もう一つセクションがあります。
その部分は4つのセクションで共有できる、いわば「共通の宣言部」であり、この「共通の宣言部」の存在が複合トリガーの大きな売りの部分であるということができます。
「共通の宣言部」で宣言した変数は、4つのセクションすべてで共有できます。

例えば、トリガーの起動順番は、とにかくまず、「BEFOREの文トリガー」が一番最初に起動します。
次に「(BEFORE/AFTER)の行トリガー」が行ごとに起動し、最後に「AFTERの文トリガー」が起動するのですが、このとき、「BEFOREの文トリガー」が処理した何らかの値を「(BEFORE/AFTER)の行トリガー」に渡したいとします。
プログラムでは値を受け渡すときは変数を使います。
しかし、複合トリガーでなく、普通のトリガー定義では、変数を使った値の受け渡しが簡単にはできません。
なぜなら各トリガーの宣言部はそのトリガーのみに有効なローカルな宣言部なので、異なるトリガー間で、一つの変数を共有できないからです。
どうしても変数を共有するのであれば、パッケージ変数を使う方法があります。
パッケージ変数はセッション毎に保持されるからです(バックナンバー第30回「パッケージでできること 変数の永続性」)。

しかし、パッケージで変数を定義し、「BEFOREの文トリガー」でその変数に値をセットし、「(BEFORE/AFTER)の行トリガー」でそれを参照するという構造では、コードがあちこちに分散していて、システムが複雑でわかりにくいものになります。

そこで、そんな時、まさにぴったりなのが「複合トリガー」です。

複合トリガーを使えば、コードがあちらこちらに分散することがなく、まとめることができます。
変数も複合トリガーで定義できて各セクションで共有できるので、パッケージ変数を使う必要はありません。
異なるトリガーで変数を共有する必要があるとき、複合トリガーを使えば簡単に対応できます。

では複合トリガーの構文ですが、以下のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*****************************************************************/
-- 複合トリガーの定義
/*****************************************************************/
CREATE OR REPLACE  TRIGGER  複合トリガー名
FOR  INSERT OR DELETE OR  UPDATE [ OF 列名,・・・]  ON 表名
/*****************************************************************/
-- 共通の宣言のセクション
/*****************************************************************/
COMPOUND  TRIGGER
    共通の宣言部(共通の変数などを宣言する)
/*****************************************************************/
-- BEFOREの文のセクション
/*****************************************************************/
BEFORE  STATEMENT IS
    ローカルな宣言部(ローカル変数などを宣言する)
BEGIN
    BEFOREの文の処理 (処理を記述する)
END  BEFORE STATEMENT;
/*****************************************************************/
-- AFTERの文のセクション
/*****************************************************************/
AFTER  STATEMENT IS
    ローカルな宣言部(ローカル変数などを宣言する)
BEGIN
    AFTER の文の処理 (処理を記述する)
END  AFTER STATEMENT;
/*****************************************************************/
-- BEFOREの行のセクション
/*****************************************************************/
BEFORE  EACH ROW  IS
    ローカルな宣言部(ローカル変数などを宣言する)
BEGIN
    BEFOREの行の処理 (処理を記述する)
END  BEFORE  EACH ROW;
/*****************************************************************/
-- AFTERの行のセクション
/*****************************************************************/
AFTER  EACH ROW  IS
    ローカルな宣言部(ローカル変数などを宣言する)
BEGIN
    BEFOREの行の処理 (処理を記述する)
END  AFTER EACH ROW;
/*****************************************************************/
-- 終わりのEND;
/*****************************************************************/
END  複合トリガー名;

以下に簡単に解説します。

4行目から、CREATE構文が始まり、5行目で、表名や、イベントのタイプ(INSERT や、UPDATE、DELETEなど)を指定します。

9行名のキーワード「COMPOUND TRIGGER」の下が、共通の宣言部(10行目)です。ここに変数など必要なものを定義します。ここに定義した変数は以下の4つのセクション全体で共有できます。

14行目から「BEFOREの文」のセクションが始まります。ISからBEGINまでの間はローカルな宣言であり、ここで宣言した変数はこのセクション内のみのスコープとなるので、複合トリガー全体で共有できるものではありません。

以下同じように、「AFTERの文」、「BEFOREの行」、「AFTERの行」の各セクションがあります。
これら4つのセクションは不要であれば省略可能ですので、必要なセクションだけを記述してください。

では、今回は構文の紹介までとして、次回は具体例について解説します。
トリガー間で変数を共有する必要がある典型的な応用例があるので、それを含めて解説します。では次回、ご期待ください。

先頭へ戻る