Skill Note

平凡なエンジニアがメモ代わりにプログラミング, インフラ, ネットワークを書き綴るブログ

[Oracle]データベーストリガーの作成方法

      2020/01/09

DMLトリガーを作成する

データベーストリガーの中でももっとも一般的なDMLトリガーの作成方法と簡単な使用方法を記載していきます。

トリガーとは?

トリガーとはあるイベントが発生した場合に自動的に実行されるプロシージャです。
下記のイベント発生時にトリガーを起動させることができます。

  • DML(DELETE, INSERT, UPDATE)
  • DDL(CREATE, ALTER, DROP)
  • データベース処理(SERVERERROR, LOGON, LOGOFF, STARTUP, SHUTDOWN)

トリガーの作成方法 

トリガーは、CREATE TRIGGER句を使用して作成します。
OR REPLACEオプションを指定すると同名のトリガーを上書きします。

CREATE [OR REPLACE] TRIGGER トリガー名

トリガーの起動タイミングを指定します。
BEFOREはテーブル更新前、AFTERはテーブル更新後にトリガーを起動させます。

{BEFORE | AFTER | INSTEAD OF}

トリガーの起動イベントを指定します。

{INSERT OR UPDATE OR DELETE}

トリガーの起動対象テーブルを指定します。

ON テーブル名

トリガーの起動回数を指定します。
FOR ECACH ROWオプションを指定すると行トリガーになり、指定しないと文トリガーになります。
行トリガーはレコードの更新毎、文トリガーはテーブルの更新毎に起動します。
1回の処理で複数行が更新された場合には、行トリガーは行数分、文トリガーは1回のみトリガーが起動します。

[FOR EACH ROW]

トリガーの起動条件を指定します。
WHENオプションを指定すると一定の条件を満たした場合にのみトリガーを起動させることができます。

[WHEN 条件式]

EMPテーブルのUPDATE後に起動する行トリガーを作成する場合

CREATE [OR REPLACE] TRIGGER トリガー名
  AFTER UPDATE ON EMP
  FOR EACH ROW

トリガー本体の作成

起動イベントでINSERT OR UPDATE OR DELETEとした場合に、トリガー内で処理を分岐するにはDMLの種類を評価します。

IF INSERTING THEN   -- INSERTの場合
  ...
ELSIF UPDATING THEN -- UPDATEの場合
  ...
ELSIF DELETING THEN -- DELETEの場合
  ...
END IF;

トリガー内で更新前後の値を参照するには、バインド変数(ホスト変数):old.列名、new.列名で参照することができます。
ただし、値が参照できるのは行トリガーのみで文トリガーは参照できません。
また、起動イベントによりold/newに格納される値が異なります。

起動イベントoldnew
INSERTNULL更新後値
UPDATE更新前値更新後値
DELETE更新前値NULL

DMLの種類を判定して更新前後の値を表示する。

BEGIN
  IF INSERTING THEN
    DBMS_OUTPUT.PUT_LINE('DML:INSERT' || ' 更新後値:' || :new.name);
  ELSIF UPDATING THEN
    DBMS_OUTPUT.PUT_LINE('DML:UPDATE' || ' 更新前値:' || :old.name || ' 更新後値:' || :new.name);
  ELSIF DELETING THEN
    DBMS_OUTPUT.PUT_LINE('DML:DELETE' || ' 更新前値:' || :old.name);
  END IF;
END;

トリガーからプロシージャを起動する。

BEGIN
  IF INSERTING THEN
    insert_proc(:new.name);
  ELSIF UPDATING THEN
    update_proc(:old.name, :new.name);
  ELSIF DELETING THEN
    update_proc(:old.name);
  END IF;
END;
/

トリガー使用時の注意点

  • トリガー内の処理でCOMMITやROLLBACKは禁止
    トリガーは上位のトランザクションよる起動されるので、トリガー内でCOMMITを行うと、上位のトランザクションでROLLBACKができなくなります。
  • 起動対象テーブルへのデータ更新
    例えば、UPDATEイベントで起動されるトリガ内でデータ更新をすると、メモリがなくなるまで再帰処理を続けます。

Google AdSense PC

Google AdSense PC

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  関連記事

sqlserer
[SQL Server]再帰SQLで集計する

WITH(共通テーブル式)を使って集計する WITH句とは 共通テーブル式 (CTE) は、単一の SELECT、INSERT、UPDATE、DELETE、CR …

oracle
[Oracle]CSALTERを使用してOracle Expressのキャラクタセットを変更する

Oracle Expressでは標準のキャラクタセットとしてAL32UTF8が設定されます。 キャラクタセットを意識しないでデータベースの移行やデータベース間の …

oracle
Oracleで文字列を全角大文字に変換する(ひらがな・カタカナの小文字(捨て仮名)対応)

Oracleの文字列検索で全角半角、大文字小文字、ひらがなカタカナを区別しないであいまい検索する場合は比較対象の文字列形式を統一する必要があります。 文字列形式 …

oracle
[Oracle]ジョブをスケジューリングして定期実行する方法

DBMS_SCHEDULERパッケージを使用したジョブスケジューリング Oracleでジョブを定期実行するには、DBMS_SCHEDULERパッケージやDBMS …

oracle
ODP.NETをNuGetからインストールする

ODP.NETのインストール手順 Oracle 12cから公式のODP.NETがNuGetに追加されました。 この記事ではODP.NETをNuGetからインスト …

oracle
[Oracle]データベースを再構築してOracle Expressのキャラクタセットを変更する

前回の記事でCSALTERを使用したキャラクタセットの変更方法を記載しましたが、サブセットのキャラクタセットからスーパセットへの変更のみ可能でした。 この記事で …

sqlserer
[SQLServer]形式指定で日付を取得する方法

SQLServerで形式を指定して日付を取得する 日付形式を指定するために、CONVERT関数、または、FORMAT関数を使用します。 CONVERT関数とFO …

oracle
[Oracle]WEBサイトやWEB APIをOracleから呼び出す方法

WEBリクエストを送信してレスポンスを表示する OracleからWEBサイトやWEB APIなどのネットワークサービスを呼び出すには、UTL_HTTPパッケージ …

oracle
Oracle12cでユーザを作成する方法

SQLコマンドを使用したユーザ作成 Oracle12cからマルチテナント・アーキテクチャが採用されており、以前までの手順ではユーザが作成できません。 ここではP …

db
[Database]データベースのバージョン/エディションを確認する方法

OracleとSQLServerのバージョン/エディションを確認 Oracle  SELECT * FROM V$VERSION SQLServer SELEC …