トリガを作成したり,トリガを削除したりするには,セクション13.1.19 " create trigger構文"およびセクション13.1.30 " drop trigger構文"で説明しているように,创建触发器
または下降触发
ステトメントを使用します。
次に,插入
操作に対してアクティブ化するトリガをテブルに関連付ける簡単な例を示します。このトリガは加算器として機能し,テブルのいずれかのカラムに挿入された値を合計します。
mysql> CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));查询OK, 0 rows affected (0.03 sec) mysql> CREATE TRIGGER ins_sum BEFORE INSERT ON account -> FOR EACH ROW SET @sum = @sum + NEW.amount;查询OK, 0行受影响(0.06秒)
创建触发器
ステトメントは,账户
テブルに関連付けられているins_sum
という名前のトリガを作成します。トリガーアクションタイム,トリガーイベント,およびトリガーがアクティブ化したときに行う動作を指定する句も含みます。
キワド
之前
は,トリガムを示します。この場合,トリガは,テーブルに挿入された各行の前にアクティブ化します。ここで許可されている別のキーワードは后
です。キワド
插入
は,トリガ,。例では,插入
操作がトリガのアクティブ化を引き起こします。删除
および更新
操作に対するトリガも作成できます。为每一行
に続くステトメントは,トリガ本体を定義します。これは,トリガーがアクティブ化するたびに実行するステートメントであり,トリガーイベントによって影響される行ごとに一度行われます。この例では,トリガ,本体は,量
カラムに挿入された値をユザ変数に累積する単純な集
です。このステトメントは,「新しい行に挿入される量
カラムの値」を意味するNEW.amount
としてカラムを参照します。
トリガを使用するには,加算器変数をゼロにセットし,插入
ステトメントを実行して,その後変数がどの値になっているかを確認します。
SET @sum = 0;mysql> INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);mysql> SELECT @sum AS 'Total amount insert ';+-----------------------+ | 插入的总量 | +-----------------------+ | 1852.48 | +-----------------------+
この場合,插入
ステトメントの実行後の@sum
の値は14.98 + 1937.50 - 100
または1852.48
です。
トリガを破棄するには,下降触发
ステトメントを使用します。トリガがデフォルトスキマにない場合,スキマ名を指定する必要があります。
mysql> DROP TRIGGER test.ins_sum;
テブルを削除すると,そのテもすべて削除されます。
トリガ名はスキマの名前空間内に存在します。。異なるスキマ内のトリガは同じ名前を持。
トリガー名はスキーマに対して一意であるという要件以外に,作成できるトリガーの種類に対して別の制限があります。特に,所定のテーブルに,同じトリガーイベントとアクションタイムを持つ複数のトリガーを含めることはできません。たとえば,1のテブルに対して2の在更新之前
トリガを定義することはできません。これに対処するために,为每一行
のあとで开始……结束
複合ステートメント構造構文を使用することにより,複数のステートメントを実行するトリガーを定義できます。(例はこのセクションであとから示します)。
トリガ本体内で,老
および新
キワドを使用すると,トリガの影響を受ける行のカラムにアクセスできます。老
および新
はトリガに対するMySQLの拡張です。これらは大文字と小文字を区別しません。
插入
トリガ内では,新的。
だけを使用できます。古い行はありません。col_name
删除
トリガでは,老了。
だけを使用できます。新しい行はありません。col_name
更新
トリガでは,老了。
を使用して,更新される前の行のカラムを参照でき,col_name
新的。
を使用して,更新されたあとの行のカラムを参照できます。col_name
老
で指名されたカラムは読み取り専用です。(それに対する选择
権限がある場合)参照はできますが,変更はできません。新
で指名されたカラムは,それに対する选择
権限がある場合に参照できます。之前
トリガでは,それに対する更新
権限がある場合,新设置。
でその値を変更することもできます。これは,トリガーを使用して,新しい行に挿入する値または行の更新に使用される値を変更できることを意味します。(このようなcol_name
=价值
集
ステトメントは,行の変更はすでに行われているため,后
トリガでは効果がありません.)
之前
トリガでは,AUTO_INCREMENT
カラムの新
値は0であり,新しい行が実際に挿入されるときに自動的に生成されるシケンス番号ではありません。
开始……结束
構造構文を使用することにより,複数のステトメントを実行するトリガを定義できます。开始
ブロック内では,条件文やループなど,ストアドルーチン内で許可されたほかの構文を使用することもできます。ただし,ストアドル,チンの場合と同様に,mysqlプログラムを使用して,複数のステトメントを実行するトリガを定義する場合,トリガ定義内で;
ステトメント区切り文字を使用できるように,mysqlステトメント区切り文字を再定義する必要があります。次の例はこれらの要点を示しています。ここでは,各行の更新に使用する新しい値をチェックし,0から100の範囲に収まるように値を変更する更新
トリガを定義しています。行の更新に使用される前に値をチェックする必要があるので,これは之前
トリガにする必要があります。
mysql> delimiter // mysql> CREATE TRIGGER upd_check BEFORE UPDATE ON account -> FOR EACH ROW -> BEGIN -> IF NEW。amount < 0 THEN ->设置新。数量= 0;- > ELSEIF新的。量> 100 THEN -> SET NEW.amount = 100; -> END IF; -> END;// mysql> delimiter ;
ストアドプロシジャを個別に定義してから,単純な调用
ステトメントを使用してトリガから呼び出したほうが簡単になる場合があります。これは,複数のトリガ内から同じコドを実行する場合にも便利です。
アクティブ化したときにトリガが実行するステトメントに表示できる対象には制限があります。
トリガは,
调用
ステートメントを使用して,データをクライアントに戻すストアドプロシージャーや,ダイナミックSQLを使用するストアドプロシージャーの呼び出しはできません。(ストアドプロシジャは,出
またはINOUT
パラメタを通じてトリガにデタを返すことが許可されています。)トリガは,
开始事务
、提交
、回滚
など,トランザクションを明示的または暗黙的に開始したり終了したりするステートメントを使用できません。
セクションd.1 "ストアドプログラムの制約"も参照してください。
MySQLは次のようにトリガ実行中にエラを処理します。
之前
トリガが失敗した場合,対応する行に対する操作は実行されません。之前
トリガは,行を挿入または変更しようとする試行によってアクティブ化され,その試行がその後成功するかどうかには関係ありません。后
トリガは,すべての之前
トリガと行操作の実行が成功した場合にのみ実行されます。之前
または后
トリガーのどちらかの実行中にエラーが発生すると,トリガーの呼び出しを起こしたステートメント全体が失敗します。トランザクションテーブルの場合,ステートメントの失敗により,ステートメントが実行したすべての変更がロールバックされます。トリガの失敗はステトメントの失敗を招くので,トリガの失敗はロルバックも引き起こします。非トランザクションテーブルの場合,このようなロールバックは行えないので,ステートメントが失敗しても,エラーの時点以前に実行されたすべて変更は有効なままです。
次の例に示すtestref
という名前のトリガなど,トリガには,名前によるテブルへの直接の参照を含めることができます。
创建表test1(a1 INT);创建表test2(a2 INT);创建表test3(a3 INT NOT NULL AUTO_INCREMENT主键);创建表test4(a4 INT NOT NULL AUTO_INCREMENT主键,b4 INT DEFAULT 0);CREATE TRIGGER testref BEFORE INSERT ON test1 FOR EACH ROW BEGIN INSERT INTO test2 SET a2 = NEW.a1;WHERE a3 = NEW.a1;SET b4 = b4 + 1 WHERE a4 = NEW.a1;结束;|分隔符;INSERT INTO test3 (a3) VALUES (NULL), (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 >插入test1值- > (1)(3)(1)(7)(1)(8),(4),(4);查询OK, 8行受影响(0.01秒)记录:8重复:0警告:0
この結果,4のテブルに次のデタが含まれます。
mysql> SELECT * FROM test1;+------+ | a1 | +------+ | 1 | | 3 | | 1 | | 7 | | 1 | | 8 | | 4 | | 4 | +------+ 8行集(0.00秒)从test2 mysql > SELECT *;+------+ | a2 | +------+ | 1 | | 3 | | 1 | | 7 | | 1 | | 8 | | 4 | | 4 | +------+ 8行集(0.00秒)从test3 mysql > SELECT *;+——+ | a3 | +----+ | 2 | | 5 | | 6 | | 9 | | 10 | +----+ 5行集(0.00秒)从test4 mysql > SELECT *;+----+------+ | a4 | b4 | +----+------+ | 1 | 3 | | 2 | 0 | | 3 | 1 | | 4 | 2 | | 5 | 0 | | 6 | 0 | | 7 | 1 | | 8 | 1 | | 9 | 0 | | 10 | 0 | +----+------+ 10行集(0.00秒)