CREATE TRIGGER 構文

CREATE
    [DEFINER = { user | CURRENT_USER }]
    TRIGGER trigger_name trigger_time trigger_event
    ON tbl_name FOR EACH ROW trigger_stmt

このステートメントによって、新しいトリガが生成されます。トリガは名称を持つ、テーブルに付属するデータベース オブジェクトで、テーブルに対して特定イベントが発生すると有効化されます。現在、CREATE TRIGGER には、そのトリガに添付したテーブルに対する TRIGGER 権限が必要です。(このステートメントは MySQL より前のバージョンに SUPER 権限を求めるものです。)

トリガは、tbl_name なる名称を持つテーブルと連携するようになり、これによって、トリガはパーマネント テーブルを参照しなければならなくなります。トリガを TEMPORARY テーブルあるいはビューと連携させる事はできません。

トリガが有効化されると、このセクションで後に述べるように DEFINER 条項によって、適用すべき権限が規定されます。

trigger_time はトリガのアクション タイムです。それを有効化するステートメントの前か後にトリガが有効化される事を示す BEFORE または AFTER となる事ができます。

trigger_event はトリガを有効化するステートメントの種類を示します。trigger_event では、以下の中から1つを選ぶ事ができます:

trigger_event は、それがテーブル 操作のタイプを表している場合には、トリガを有効化する SQL ステートメントのリテラル タイプを表さないと理解する事が重要です。例えば、ステートメントは両方共行をテーブルに挿入するので、INSERTトリガは、INSERT ステートメントのみならず、LOAD DATA ステートメントによっても有効化されます。

この潜在的に紛らわしい例は、INSERT INTO ... ON DUPLICATE KEY UPDATE ... という構文です: BEFORE INSERT トリガは、全ての行に対して有効化され、その後、行に対して重複キーがあるか否かによって、AFTER INSERT トリガもしくは BEFORE UPDATE トリガと AFTER UPDATE トリガの両方が有効化されます。

同じトリガ アクション タイムとトリガ イベントを持つテーブルに対して、2つのトリガは存在する事はできません。例えば、1個のテーブルに対して2つの BEFORE UPDATE トリガを持つ事はできません。しかし、BEFORE UPDATE トリガと BEFORE INSERT トリガもしくは BEFORE UPDATE トリガと AFTER UPDATE トリガを持つ事ができます。

trigger_stmt はトリガを有効化する時に実行させるステートメントです。複数の命令を実行させたい場合には、BEGIN ... END 複合文コンストラクトを使ってください。これは、ストアド ルーチン内で許されているのと同じステートメントも使う事ができるようにします。項 「BEGIN ... END 複合ステートメント構文」 を参照してください。トリガ中に同じステートメントを使用する事は許されません。(項D.1. 「ストアド ルーチンとトリガの規制」 を参照)。

MySQL は sql_mode システム中に、トリガが生成された時に有効であった変数設定を記憶し、現サーバの SQL モードに関係なく、この設定でトリガを実際に実行します。

:トリガは現在、転送された外部キー アクションによって有効化されません。この制限はできるだけ早く撤廃されるでしょう。

MySQL 5.1 で、この例に示す testref という名前のトリガのような、直接の参照を含むトリガを名称別テーブルに書き込む事ができます:

CREATE TABLE test1(a1 INT);
CREATE TABLE test2(a2 INT);
CREATE TABLE test3(a3 INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE test4(
  a4 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
  b4 INT DEFAULT 0
);

DELIMITER |

CREATE TRIGGER testref BEFORE INSERT ON test1
  FOR EACH ROW BEGIN
    INSERT INTO test2 SET a2 = NEW.a1;
    DELETE FROM test3 WHERE a3 = NEW.a1;  
    UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1;
  END;
|

DELIMITER ;

INSERT INTO test3 (a3) VALUES 
  (NULL), (NULL), (NULL), (NULL), (NULL), 
  (NULL), (NULL), (NULL), (NULL), (NULL);

INSERT INTO test4 (a4) VALUES 
  (0), (0), (0), (0), (0), (0), (0), (0), (0), (0);

以下の値をテーブル test1 に、ここに示すように挿入すると仮定します:

mysql> INSERT INTO test1 VALUES 
    -> (1), (3), (1), (7), (1), (8), (4), (4);
Query OK, 8 rows affected (0.01 sec)
Records: 8  Duplicates: 0  Warnings: 0

結果として、4つのテーブル中のデータは以下の通りになります:

mysql> SELECT * FROM test1;
+------+
| a1   |
+------+
|    1 |
|    3 |
|    1 |
|    7 |
|    1 |
|    8 |
|    4 |
|    4 |
+------+
8 rows in set (0.00 sec)

mysql> SELECT * FROM test2;
+------+
| a2   |
+------+
|    1 |
|    3 |
|    1 |
|    7 |
|    1 |
|    8 |
|    4 |
|    4 |
+------+
8 rows in set (0.00 sec)

mysql> SELECT * FROM test3;
+----+
| a3 |
+----+
|  2 |
|  5 |
|  6 |
|  9 |
| 10 |
+----+
5 rows in set (0.00 sec)

mysql> SELECT * FROM test4;
+----+------+
| a4 | b4   |
+----+------+
|  1 |    3 |
|  2 |    0 |
|  3 |    1 |
|  4 |    2 |
|  5 |    0 |
|  6 |    0 |
|  7 |    1 |
|  8 |    1 |
|  9 |    0 |
| 10 |    0 |
+----+------+
10 rows in set (0.00 sec)

エイリアス OLD とエイリアス NEW を使う事によって、問題のテーブル(トリガに添付されたテーブル)中のカラムを参照する事ができます。OLD.col_name は既存の行のカラムが更新または削除される前にチェックします。NEW.col_name は挿入すべき新しい行あるいは更新された既存の行のカラムを参照します。

DEFINER 条項は、トリガの有効化においてアクセス権をチェックする時に使用すべき MySQL アカウントを指定します。user 値を附与する場合、それを 'user_name'@'host_name' フォーマット(GRANT ステートメントに使用したのと同じフォーマット)の中にある MySQL アカウントとするべきです。user_name の値と host_name の値が両方共必要です。CURRENT_USERCURRENT_USER() として附与する事もできます。DEFINER のデフォルト値は CREATE TRIGGER ステートメントを実行するユーザです。(これは DEFINER = CURRENT_USER と同じです。)

DEFINER 条項を特定する場合、SUPER 権限を保持していない限り、自分の値を除くいかなるアカウントにも値をセットする事はできません。これらの規則は有効な DEFINER ユーザ値を決定します:

注意:MySQL 5.1.6以前のバージョンでは、MySQL は CREATE TRIGGER を使用する為に SUPER権限を要求するので、前の規則の2番目の規定だけが適用されます。5.1.6以降のバージョンからは、CREATE TRIGGERTRIGGER 権限を要求し、SUPER 権限は、DEFINERに自身のアカウント値以外の値をセットする事を可能にする為だけに要求されます。

MySQL は、このようなトリガ権限をチェックします: