MySQL AFTER 更新触发器与 New.col<> OLD.col

Posted

技术标签:

【中文标题】MySQL AFTER 更新触发器与 New.col<> OLD.col【英文标题】:MySQL AFTER Update trigger with New.col<> OLD.col 【发布时间】:2015-03-26 11:11:31 【问题描述】:

这里的目标是根据条件更新和连接一个表中的文本字段到另一个表。当使用用户表单中的某些文本更新文本列时,运行更新后触发器。

触发器运行但更新所有列,而不仅仅是已更改的列。尝试了解如何仅更新正确的行。

这是我到目前为止所拥有的- SQLFiddle

| ID | SUBID | SWNOTES |
|----|-------|---------|     Table 1
|  1 |    40 |    test |
|  2 |    60 |         |



| ID | SUBID | CONTENT | SWFLAG |
|----|-------|---------|--------|
|  1 |    40 |   hello |      0 |     Table 2
|  2 |    60 | nothing |      0 |


CREATE TRIGGER `updatecontentnotes` AFTER UPDATE ON `tab1`
 FOR EACH ROW 
BEGIN

IF New.swnotes <> OLD.swnotes
THEN
    Update `tab2` 
Inner Join `tab1` ON `tab2`.`subid` = `tab1`.`subid` 
Set `tab2`.`swflag` = '1',`tab2`.`content` = CONCAT(`tab2`.`content`, `tab1`.`swnotes`)

Where `tab2`.`subid` = `tab1`.`subid` AND `tab2`.`swflag` = '0';

END IF;

END//

如果我用say更新表格:

  Update `tab1`
set `swnotes` = "new"
where `subid` = '60'

我明白了:

| ID | SUBID |    CONTENT | SWFLAG |
|----|-------|------------|--------|
|  1 |    40 |  hellotest |      1 |
|  2 |    60 | nothingnew |      1 |

现在我知道它正在做我告诉它做的事情。我只想更新已更新的行。感谢您对此的任何帮助。

【问题讨论】:

【参考方案1】:

由于您的触发器的内容将针对tab1 上的每一行运行,因此您需要在WHERE 子句中更加严格,以便它只会影响已更新的行。现在它更新tab2上的每一行

尝试将此添加到您的触发器 SQL:

发件人:

Where `tab2`.`subid` = `tab1`.`subid` AND `tab2`.`swflag` = '0';

收件人:

Where `tab2`.`subid` = `tab1`.`subid` AND `tab2`.`swflag` = '0' AND `tab2`.`id` = OLD.id;

这会产生我认为您正在寻找的结果:

| ID | SUBID |    CONTENT | SWFLAG |
|----|-------|------------|--------|
|  1 |    40 |      hello |      0 |
|  2 |    60 | nothingnew |      1 |

更新的 SQLFiddle 在这里:

http://sqlfiddle.com/#!2/9fa2d2/1/0

【讨论】:

以上是关于MySQL AFTER 更新触发器与 New.col<> OLD.col的主要内容,如果未能解决你的问题,请参考以下文章

对于50000行的表,MySQL触发器AFTER UPDATE执行速度极慢

SQL AFTER 插入更新触发器

AFTER UPDATE 触发器使用更新表中的聚合

在AFTER UPDATE触发器上尝试更新只读列错误

mysql触发器Before和After的区别

mysql之触发器before和after的区别