このセクションで、MySQL 5.1の中でトリガーを使用する方法並びにこれらの使用に対する幾つかの制限について説明します。トリガーに対する制約に関する追加情報を、 Restrictions on Stored Routines and Triggersに掲載します。
トリガーは名称を持つ、テーブルに付属するデータベースオブジェクトで、テーブルに対して特定イベントが発生すると有効化されます。幾つかは、トリガーに対して、テーブルに挿入すべき値を対象にチェックを実施するか、更新に含まれる値に関して、計算を実行するのに使用されます。
INSERT命令文、DELETE命令文もしくはUPDATE命令文がテーブルに対して実行されると、トリガーがテーブルに結び付けられ、規定されて有効化されます。トリガーはその命令の前か後にセットして有効化することができます。例えば、あなたはトリガーを、各横列をテーブルから削除する前または各横列を更新した後に有効化させることができます。
CREATE TRIGGER命令文またはDROP TRIGGER命令文を使ってトリガーを生成させるか除去してください。これらの命令文に対するシンタックスは、 項3.1. 「CREATE TRIGGER 構文」 および 項3.2. 「DROP TRIGGER 構文」に掲載してあるのでご覧ください。
INSERT命令文のためのテーブルをトリガーに添付した例をここに紹介します。それはそのテーブルのこらむの1つに挿入された値を合計する加算器の役を果たします。
以下の命令文によって、テーブルとそれに対するトリガーが生成されます。
mysql>CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));mysql>CREATE TRIGGER ins_sum BEFORE INSERT ON account->FOR EACH ROW SET @sum = @sum + NEW.amount;
CREATE TRIGGER命令文は、accountを付随して持ち、ins_sumなる名称のトリガーを生成させます。それには、トリガーに対する有効化の時期、トリガーエベント並びにトリガーの有効化に要するその他を規定する条項も含まれています。
キーワードBEFORE はトリガーアクションの時期を示します。この場合、トリガーを各横列がテーブルに挿入される前に有効化すべきです。ここで許容されるその他のキーワードはAFTERです。
キーワードINSERT はトリガーを有効化するエベントを示します。例では、INSERT 命令文によってトリガーの有効化が引き起こされます。あなたはDELETE命令文およびUPDATE命令文に対してトリガーを生成させることができます。
FOR EACH ROWの後に連なる命令文は、トリガーを有効化するたびに実行すべき命令文を規定します。これは、トリガーに対する命令文によって影響を被る各横列毎に一回発生します。この例では、トリガー命令文は、amount欄に挿入された値を集計する簡単なSETです。その命令文には、そのカラムが新しい横列に挿入すべき「amountコラムの値を意味する」NEW.amountとして引用されます。
トリガー使うために、 加算器変数をゼロにセットしてINSERT命令を実行し、その後変数がどんな値になったか調べます:
mysql>SET @sum = 0;mysql>INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);mysql>SELECT @sum AS 'Total amount inserted';+-----------------------+ | Total amount inserted | +-----------------------+ | 1852.48 | +-----------------------+
この場合、INSERT命令が実行された後に付けられた@sumの値は14.98 + 1937.50 - 100あるいは1852.48です。
トリガーを破壊するため、DROP TRIGGER命令文を使います。そのトリガーが初期設定スキーマに含まれていない場合には、あなたはスキーマ名を規定しなければなりません。
mysql> DROP TRIGGER test.ins_sum;
スキーマの名称欄にトリガー名が存在しています。これは、全てのトリガーはスキーマの中にユニークな名称を持っていなければならないことを意味します。異なったスキーマの中にあるトリガーに同じ名称を付けることができます。
スキーマ毎にトリガー名をユニークなものとすべき要件に加え、あなたが生成させることができるトリガーのタイプに他の制限があります。特に、あなたは有効化の時期と有効化エベントが同じ1つのテーブルに対して、2個のトリガーを持つことはできません。例えば、あなたは1つのテーブルに対して、2つのBEFORE INSERTトリガーもしくは2つのAFTER UPDATEトリガーを規定することはできません。 (このセクションの後の部分に述べる)BEGIN ... END合成命令文の構築をFOR EACH ROWの後に使うことによって、複数の命令を実行するトリガーを規定することができるので、これを重要な制限とみなすべきではありません。
OLD なるキーワードとNEWなるキーワードを使用すると、トリガーによって影響を被る横列中のコラムにアクセスすることが可能となります。 ((OLDとNEWは大文字でも小文字でも入力することができます。)INSERTトリガーの場合、NEW.だけが使用可能です。古い横列は存在しません。col_nameDELETEトリガーの場合、OLD.だけが使用可能です。新しい横列は存在しません。col_nameUPDATE トリガーの場合、OLD.を使ってアップデート前の横列のコラムを、またcol_nameNEW.を使用して、アップデート後の横列のコラムをそれぞれ参照することができます。col_name
OLDの名称を持つコラムは読み取り専用です。(SELECT特権をお持ちである場合)、あなたはそれを調べることができますが、改訂することはできません。SELECT特権をお持ちの場合、あなたはNEWの名称を持つコラムを調べることができます。BEFORE トリガーでは、UPDATE特権をお持ちの場合、あなたはSET NEW.を使ってその値に変更を施すことができます。これは、あなたはトリガーを使って、新しい横列に挿入すべきか横列を更新するのに使用する値を改訂することができることを意味します。col_name = value
BEFOREトリガーでは、AUTO_INCREMENT カラムに対するNEW値は、新しい記録を実際に挿入するとき自動的に生成されるシーケンスナンバーでなく、0となります。
OLDとNEWはトリガーに対するMySQLの延長部分です。
BEGIN ... END 構築を使用することによって、あなたは複数の命令を実行するトリガーを規定することができます。BEGINブロックの中で、条件文やループのような記憶ルーチンの中で許されているその他のシンタックスを使用することもができます。しかし、記憶ルーチンだけに対して、複数の命令を実行する1個のトリガーを規定する mysqlプログラムを使用した場合、 mysql命令文デリミタを再定義して、トリガーの定義の中で;命令文デリミタを使用可能にする必要があります。 次の例はこれらの点を例示しています。それは、各横列を更新するのに使用すべき値をチェックするUPDATEトリガーを規定し、その値を0から100までの範囲に収まるように改訂します。その値は、横列を更新するのに使用する前にチェックする必要があるので、BEFOREトリガーでなければなりません。
mysql>delimiter //mysql>CREATE TRIGGER upd_check BEFORE UPDATE ON account->FOR EACH ROW->BEGIN->IF NEW.amount < 0 THEN->SET NEW.amount = 0;->ELSEIF NEW.amount > 100 THEN->SET NEW.amount = 100;->END IF;->END;//mysql>delimiter ;
記憶されている手順を別々に定義して、次に単純なCALL 命令を使ってそれを呼び出して、簡素化することができます。これは、幾つかのトリガーから同じルルーチンを呼び出したい場合にも有益です。
有効化する時トリガーが実行する命令文に記載することができるものに対して、幾つかの制限があります。
トリガーは、データを顧客に戻すかダイナミックSQLを使用する、記憶された手順を呼び出すCALL命令文を使用するこができません。(記憶された手順は、OUTまたはINOUTパラメータを通してトリガーにデータを戻すことを許します。)
トリガーは、START TRANSACTION、COMMITやROLLBACKのような取引を明確もしくは暗黙裏に開始するか終わらせる命令文を使用することができません。
MySQLはトリガーを実行している最中に発生したエラーを以下の通りに処理します:
BEFOREトリガーの機能が停止した場合、対応する横列の操作が実施されなくなる。
BEFOREトリガーが、横列を挿入するか改訂するattempt によって、当該試みがその後成功するか否かに関係なく有効化される。
AFTERトリガーが、BEFOREトリガー(存在している場合) 並びに横列オペラーションが両方共うまく実行された場合に限り実行される。
BEFOREトリガーあるいはAFTERトリガーを実行している最中に発生したエラーが、トリガーに狂いを引き起こし、これによって、全命令文を機能停止にする。
取引テーブルに対する命令文の機能停止は、その命令文によって実施された一切の変更の撤回を引き起こすべきです。トリガーの機能停止は、命令文に機能停止をもたらし、これによって、トリガーの機能停止が巻き返し引き起こす。非取引テーブルに対してこのような巻き返しを行うことがでないので、命令文が機能停止しても、エラーが発生した時点より前に実施された一切の変更は有効なまま維持されます。
