未変更の行に対して MySQL トリガーが実行されないようにします
MySQL トリガーは、挿入、更新、削除などの特定の操作がテーブルで発生したときに実行されます。ただし、デフォルトでは、テーブルの行に変更が加えられていない場合でも、「更新後」トリガーがアクティブになります。
変更がない場合でも「更新後」トリガーが実行されるのはなぜですか?
更新された行の変更を検出する通常の方法は、行の「新しい」バージョンと「古い」バージョンの間で個々の列の値を比較することです。ただし、テーブル内の列の数が増えると、このアプローチは退屈になり、エラーが発生しやすくなります。
解決策: 行のタイムスタンプを活用して変更を識別します
この問題を解決する優れた方法は、行タイムスタンプ列を使用することです。 MySQL は、行ごとに作成タイムスタンプと更新タイムスタンプの 2 つのタイムスタンプ列を保持します。これらのタイムスタンプは、行が挿入または更新されるたびに自動的に更新されます。
タイムスタンプの比較に基づいて実行をトリガーします
新しいタイムスタンプと古いタイムスタンプを比較することで、行に変更が加えられたかどうかを判断できます。次のトリガー コードは、このアプローチを示しています:
<code class="language-sql">CREATE TRIGGER ins_sum AFTER UPDATE ON foo FOR EACH ROW BEGIN IF NEW.ts <> OLD.ts THEN -- 已进行更改;执行触发器主体 END IF; END;</code>
このトリガーでは、「NEW.ts」と「OLD.ts」がそれぞれ新しいタイムスタンプ値と古いタイムスタンプ値を表します。値が異なる場合、変更が発生し、トリガー本体が実行されます。
例
次の例を考えてみましょう:
<code class="language-sql">CREATE TABLE foo (a INT, b INT, ts TIMESTAMP); -- 插入一些行 INSERT INTO foo (a, b) VALUES (1, 1); INSERT INTO foo (a, b) VALUES (2, 2); INSERT INTO foo (a, b) VALUES (3, 3); -- 触发器定义 DELIMITER /// CREATE TRIGGER ins_sum AFTER UPDATE ON foo FOR EACH ROW BEGIN IF NEW.ts <> OLD.ts THEN INSERT INTO bar (a, b) VALUES (NEW.a, NEW.b); END IF; END; /// DELIMITER ; -- 不更改地更新 UPDATE foo SET b = 3 WHERE a = 3; -- 更改地更新 UPDATE foo SET b = 4 WHERE a = 3;</code>
最初の更新を実行した後 (変更を加えない場合)、トリガーは実行されません。ただし、2 回目の更新で行が変更され、トリガーが実行され、新しい行が「bar」テーブルに挿入されます。
このソリューションにより、個々の列の値を明示的に比較する必要がなくなり、行に実際の変更が加えられた場合にのみトリガーが実行されるようになります。
以上がMySQL の「AFTER UPDATE」トリガーが変更されていない行に対して起動しないようにするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。