CREATE
[DEFINER = { user | CURRENT_USER }]
TRIGGER trigger_name trigger_time trigger_event
ON tbl_name FOR EACH ROW trigger_stmt
この命令文によって、新しいトリガーが生成されます。トリガーは名称を持つ、テーブルに付属するデータベースオブジェクトで、テーブルに対して特定イベントが発生すると有効化されます。現在、CREATE TRIGGER には、そのトリガー に添付したテーブルに対するTRIGGER特権が必要です。(この命令文は MySQL 5.1.6.より前にSUPER特権を求めるものです。)
トリガーは、tbl_name なる名称を持つテーブルと連携するようになります。これによって、トリガーは永久テーブルを参照しなければならなくなります。あなたはトリガーを TEMPORARY テーブルあるいは画面と連携させることはできません。
トリガーが有効化されると、このセクションで後に述べる定義条項(DEFINERClause)によって、適用すべき特権が規定されます。
trigger_timeはトリガーのアクションタイムです。それを有効化する命令文の前か後にトリガーが有効化されることを示すBEFOREまたはAFTERにすることができます。
trigger_eventはトリガーを有効化する命令文の種類を示します。trigger_eventでは、以下の中から一つを選ぶことができます:
INSERT:トリガーは、新しい横列がテーブルに挿入されると必ず、例えばINSERT、 LOAD DATA並びにREPLACEの各命令文を通して有効化されます。
UPDATE:トリガーは、横列が修正されると必ず、例えばUPDATE命令文を通して有効化されます。
DELETE:トリガーは、新しい横列がテーブルに挿入されると必ず、例えばDELETE命令文並びにREPLACE命令文を通して有効化されます。しかし、テーブル上のDROP TABLE 命令文およびTRUNCATE命令文は、DELETEを使用していないので、このトリガーを有効化しません。区画を撤去すると、DELETEトリガーも一緒に無有効化されます。詳しくはTRUNCATE Syntaxを参照してください。
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 Compound Statement Syntaxをご確認ください。トリガー中に同じ命令文を使用することは許されません。(Restrictions on Stored Routines and Triggersを参照)。
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_nameNEW.は挿入すべき新しい横列あるいは既存の横列の欄を更新された後にチェックします。col_name
DEFINER条項は、トリガーの有効化においてアクセス権をチェックするとき使用すべきMySQLアカウントを指定します。user値を附与する場合、それを「'フォーマット(user_name'@'host_name'GRANT命令文に使用したと同じフォーマット)の中にあるMySQLアカウントにすべきです。user_name の値とhost_name の値が両方共必要です。CURRENT_USERをCURRENT_USER()として附与することもできます。DEFINERの初期値はCREATE TRIGGER命令文を実行するユーザーです。(これはDEFINER = CURRENT_USERと同じです。)
DEFINER条項を規定する場合、あなたは、SUPER特権を持っていない限り、自分の値を除くいかなるアカウントにも値をセットすることはできません。これらの規則はDEFINERユーザーの法定値を査定します:
あなたがSUPER特権を持っていない場合、文字によるか、CURRENT_USERを使って規定されているuser法定値だけがあなた自身のアカウントとなります。あなたはデファイナーに幾つかの別なアカウントを設定することはできません。
あなたがSUPER特権を持っている場合、シンタックスを使って規定した法的に有効なアナウントネームを規定することができます。そのアカウントが実在しない場合、警告が生成されます。
実在しないDEFINER値を使ってトリガーを生成させることは可能ですが、デファイナーが実在するようになるまで、このようなトリガーを有効化しておくことは決して良いアイデアではありません。さもなければ、特権チェックに関する挙動パターンは規定されません。
注:MySQL 5.1.6の前に、 MySQLはCREATE TRIGGERを使用するため、SUPER特権特典を要求するので、前の規則の2番目の規定だけが適用されます。5.1.6付けCREATE TRIGGERはTRIGGER特権を要求しますが、SUPER特権は、DEFINERにあなた自身のアカウント値以外の値をセットすることを可能にする場合に限り要求されます。
MySQL は、このようなトリガー特権をチェックします。
命令文を発行するユーザーはCREATE TRIGGERを運転する時、TRIGGER 特権を持っていなければなりません。((MySQL 5.1.6.前のSUPER)
トリガーを有効化する時、特権が DEFINER ユーザーのものであるかチェックされます。このユーザーは、これらの特権を持っていなければなりません。
TRIGGER 特権。.((MySQL 5.1.6.前のSUPER)
トリガーの定義の中にあるOLD. あるいは col_nameNEW.を経由して照合が行われる場合に得られる問題のテーブルに対するcol_nameSELECT特権。
テーブルカラムが、SET NEW. トリガーの定義中の値の割り当てターゲットである場合に得られる問題のテーブルに対するcol_name = valueUPDATE 特権。
トリガーによって命令文が実行されるために一般に要求されるその他一切の特権。
