CREATE
[DEFINER = user]
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
[trigger_order]
trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }
trigger_order: { FOLLOWS | PRECEDES } other_trigger_name
このステートメントは、新しいトリガーを作成します。 トリガーとは、テーブルに関連付けられ、そのテーブルに対して特定のイベントが発生するとアクティブ化される名前付きデータベースオブジェクトのことです。 トリガーは、tbl_name
という名前のテーブルに関連付けられます。これは、永続的なテーブルを指す必要があります。 トリガーを TEMPORARY
テーブルまたはビューに関連付けることはできません。
トリガー名はスキーマの名前空間内に存在します。つまり、すべてのトリガーがスキーマ内で一意の名前を持つ必要があります。 異なるスキーマ内のトリガーは同じ名前を持つことができます。
このセクションでは、CREATE TRIGGER
構文について説明します。 詳細は、セクション25.3.1「トリガーの構文と例」を参照してください。
CREATE TRIGGER
には、このトリガーに関連付けられたテーブルに対する TRIGGER
権限が必要です。 DEFINER
句が存在する場合、セクション25.6「ストアドオブジェクトのアクセス制御」 で説明されているように、必要な権限は user
の値によって異なります。 バイナリロギングが有効になっている場合は、セクション25.7「ストアドプログラムバイナリロギング」 で説明されているように、CREATE TRIGGER
に SUPER
権限が必要になることがあります。
DEFINER
句は、このセクションのあとの方で説明されているように、トリガーのアクティブ化時にアクセス権限を確認するときに使用されるセキュリティーコンテキストを決定します。
trigger_time
は、このトリガーのアクション時間です。 これは、トリガーが各行の変更の前またはあとにアクティブ化されることを示す BEFORE
または AFTER
にすることができます。
基本的なカラム値チェックはトリガーのアクティブ化の前に行われるため、BEFORE
トリガーを使用して、カラムタイプに不適切な値を有効な値に変換することはできません。
trigger_event
は、このトリガーをアクティブ化する操作の種類を示します。 次の trigger_event
値が許可されます。
INSERT
: トリガーは、新しい行がテーブルに挿入されるたびにアクティブ化されます (たとえば、INSERT
、LOAD DATA
およびREPLACE
ステートメントを使用)。UPDATE
: トリガーは、(UPDATE
ステートメントなどを使用して) 行が変更されるたびにアクティブ化されます。DELETE
: トリガーは、(DELETE
ステートメントやREPLACE
ステートメントなどを使用して) 行がテーブルから削除されるたびにアクティブになります。 テーブルに対するDROP TABLE
およびTRUNCATE TABLE
ステートメントは、DELETE
を使用しないため、このトリガーをアクティブ化しません。 また、パーティションを削除してもDELETE
トリガーはアクティブ化されません。
trigger_event
は、トリガーをアクティブ化する SQL ステートメントのリテラル型を表しているのではなく、テーブル操作の種類を表しています。 たとえば、INSERT
トリガーは、INSERT
ステートメントだけでなく、LOAD DATA
ステートメントでもアクティブ化されます。それは、どちらのステートメントもテーブルに行を挿入するためです。
この混乱を招く可能性がある例として、INSERT INTO ... ON DUPLICATE KEY UPDATE ...
構文があります。すべての行で BEFORE INSERT
トリガーがアクティブ化されたあと、その行に重複キーが存在したかどうかに応じて、AFTER INSERT
トリガーだけか、または BEFORE UPDATE
トリガーと AFTER UPDATE
トリガーの両方がアクティブ化されます。
カスケードされた外部キーアクションはトリガーをアクティブ化しません。
同じトリガーイベントおよびアクション時間を持つ特定のテーブルに対して複数のトリガーを定義できます。 たとえば、1 つのテーブルに対して 2 つの BEFORE UPDATE
トリガーを定義できます。 デフォルトでは、同じトリガーイベントおよびアクション時間を持つトリガーは、作成された順序で実行されます。 トリガー順序に影響を与えるには、FOLLOWS
または PRECEDES
を示す trigger_order
句と、同じトリガーイベントおよびアクション時間を持つ既存のトリガーの名前を指定します。 FOLLOWS
を指定すると、新しいトリガーは既存のトリガーのあとに実行されます。 PRECEDES
を指定すると、新しいトリガーは既存のトリガーの前に実行されます。
trigger_body
は、トリガーがアクティブ化されるときに実行されるステートメントです。 複数のステートメントを実行するには、BEGIN ... END
複合ステートメント構造構文を使用します。 これにより、ストアドルーチン内で許可されているものと同じステートメントを使用することもできます。 セクション13.6.1「BEGIN ... END 複合ステートメント」を参照してください。 一部のステートメントは、トリガー内では許可されません。セクション25.8「ストアドプログラムの制約」を参照してください。
トリガー本体内では、エイリアス OLD
と NEW
を使用して、対象テーブル (そのトリガーに関連付けられたテーブル) 内のカラムを参照できます。 OLD.
は、更新または削除される前の既存の行のカラムを示します。 col_name
NEW.
は、挿入された新しい行、または更新されたあとの既存の行のカラムを示します。
col_name
トリガーは、NEW.
または col_name
OLD.
を使用して生成されたカラムを参照することはできません。 生成されるカラムの詳細は、セクション13.1.20.8「CREATE TABLE および生成されるカラム」 を参照してください。
col_name
MySQL は、トリガーが作成されたときの有効な sql_mode
システム変数の設定を格納し、トリガーが実行を開始したときの現在のサーバー SQL モードには関係なく、常にそのトリガー本体を強制的にこの設定で実行します。
DEFINER
句は、トリガーのアクティブ化時にアクセス権限を確認するときに使用される MySQL アカウントを指定します。 DEFINER
句が存在する場合、user
値は'
、user_name
'@'host_name
'CURRENT_USER
または CURRENT_USER()
として指定された MySQL アカウントである必要があります。 許可される user
値は、セクション25.6「ストアドオブジェクトのアクセス制御」 で説明されているように、保持する権限によって異なります。 トリガーセキュリティの詳細は、そのセクションも参照してください。
DEFINER
句を省略すると、デフォルトの定義者は CREATE TRIGGER
ステートメントを実行するユーザーになります。 これは、明示的に DEFINER = CURRENT_USER
を指定するのと同じです。
MySQL は、トリガー権限を確認するときに、DEFINER
ユーザーを次のように考慮します。
CREATE TRIGGER
の時点で、このステートメントを発行するユーザーにはTRIGGER
権限が必要です。-
トリガーのアクティブ化時、権限は
DEFINER
ユーザーに対して確認されます。 このユーザーには、次の権限が必要です。対象テーブルに対する
TRIGGER
権限。テーブルカラムへの参照がトリガー本体内の
OLD.
またはcol_name
NEW.
を使用して発生した場合は、対象テーブルに対するcol_name
SELECT
権限。テーブルカラムがトリガー本体内の
SET NEW.
割り当てのターゲットである場合は、対象テーブルに対するcol_name
=value
UPDATE
権限。その他のどのような権限も、通常、そのトリガーによって実行されるステートメントに必要です。
トリガー本体内で、CURRENT_USER
関数は、トリガーのアクティブ化時に権限を確認するために使用されるアカウントを返します。 これは、そのトリガーがアクティブ化される原因となるアクションを実行したユーザーではなく、DEFINER
ユーザーです。 トリガー内のユーザー監査については、セクション6.2.22「SQL ベースのアカウントアクティビティ監査」を参照してください。
LOCK TABLES
を使用してトリガーを含むテーブルをロックした場合は、LOCK TABLES とトリガーで説明されているように、そのトリガー内で使用されているテーブルもロックされます。
トリガーの使用の詳細は、セクション25.3.1「トリガーの構文と例」を参照してください。