为了账号安全,请及时绑定邮箱和手机立即绑定

MySQL仅在行已更改时才更新

MySQL仅在行已更改时才更新

蝴蝶不菲 2019-08-12 17:18:19
MySQL仅在行已更改时才更新是否有可能仅在数据被真正改变的情况下使用“更新后”触发器。我知道“新旧”。但是在使用它们时我只能比较列。例如“NEW.count <> OLD.count”。但我想要的是:如果“NEW <> OLD”则运行触发器一个例子:create table foo (a INT, b INT);create table bar (a INT, b INT);INSERT INTO foo VALUES(1,1);INSERT INTO foo VALUES(2,2);INSERT INTO foo VALUES(3,3);CREATE TRIGGER ins_sum    AFTER UPDATE ON foo    FOR EACH ROW    INSERT INTO bar VALUES(NEW.a, NEW.b);UPDATE foo SET b = 3 WHERE a=3;Query OK, 0 rows affected (0.00 sec)Rows matched: 1  Changed: 0  Warnings: 0select * from bar;+------+------+| a    | b    |+------+------+|    3 |    3 |+------+------+关键是,有一个更新,但没有任何改变。但无论如何都触发了触发器。恕我直言应该有一种方式它没有。我知道我可以使用如果NOW.b <> OLD.b对于这个例子。想象一下有一个变化列的大桌子。您必须比较每一列,如果数据库发生更改,则必须调整触发器。并且比较硬编码的行的每一列并不“感觉”好:)加成正如你所看到的那样匹配的行数:1已更改:0警告:0MySQL知道该行没有改变。但它不会与触发器分享这些知识。像“AFTER REAL UPDATE”之类的触发器或类似的东西会很酷。
查看完整描述

3 回答

?
慕莱坞森

TA贡献1810条经验 获得超4个赞

想象一下有一个变化列的大桌子。您必须比较每一列,如果数据库发生更改,则必须调整触发器。并且比较每行硬编码并不“感觉”好:)

是的,但这是继续进行的方式。

作为旁注,在更新之前进行先发制人检查也是一种好习惯:

UPDATE foo SET b = 3 WHERE a=3 and b <> 3;

在您的示例中,这将使它更新(并因此覆盖行而不是三行。


查看完整回答
反对 回复 2019-08-12
?
芜湖不芜

TA贡献1796条经验 获得超7个赞

我不能发表评论,所以请注意,如果你的列支持NULL值,OLD.x <> NEW.x就不够了,因为

SELECT IF(1<>NULL,1,0)

返回0与...相同

NULL<>NULL 1<>NULL 0<>NULL 'AAA'<>NULL

因此它不会跟踪FROM和TO NULL的变化

这种情况下的正确方法是

((OLD.x IS NULL AND NEW.x IS NOT NULL) OR (OLD.x IS NOT NULL AND NEW.x IS NULL) OR (OLD.x<>NEW.x))


查看完整回答
反对 回复 2019-08-12
  • 3 回答
  • 0 关注
  • 613 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信