10bet网址
MySQL 5.6リファレンスマニュアル
本手册下载
PDF (Ltr)- 26.8 mb
PDF (A4)- 26.8 mb
HTML下载(TGZ)- 7.2 mb
HTML下载(邮政编码)- 7.2 mb


20.3.1トリガ

トリガを作成したり,トリガを削除したりするには,セクション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秒)