首页 > 数据库 > mysql教程 > 如何防止 MySQL'更新后”触发器在未更改的行上触发?

如何防止 MySQL'更新后”触发器在未更改的行上触发?

DDD
发布: 2025-01-13 22:38:47
原创
511 人浏览过

How Can I Prevent MySQL

避免MySQL触发器在未修改行上执行

MySQL触发器在表上发生特定操作(如插入、更新或删除)时执行。但是,默认情况下,“after update”触发器即使没有对表行进行任何更改也会激活。

为什么“After Update”触发器即使没有更改也会执行?

检测更新行中更改的常规方法是比较行的“新”版本和“旧”版本之间的各个列值。但是,随着表中列数的增加,这种方法变得繁琐且容易出错。

解决方案:利用行时间戳来确定更改

解决此问题的一个巧妙方法是使用行时间戳列。MySQL为每一行维护两列时间戳:创建时间戳和更新时间戳。每当插入或更新一行时,这些时间戳都会自动更新。

基于时间戳比较的触发器执行

通过比较新的和旧的时间戳,我们可以确定是否对行进行了更改。以下触发器代码说明了这种方法:

<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>
登录后复制

执行第一次更新(不进行任何更改)后,触发器不会运行。但是,第二次更新会更改该行,并且会执行触发器,从而将新行插入到“bar”表中。

此解决方案无需显式比较各个列值,并确保仅在对行进行实际更改时才执行触发器。

以上是如何防止 MySQL'更新后”触发器在未更改的行上触发?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板