在触发器中UPDATE后更新同一行

11

我希望epc列始终为earnings/clicks。为此,我使用了一个AFTER UPDATE触发器来实现。因此,如果我向此表中添加100个点击,我希望EPC会自动更新。

我正在尝试:

CREATE TRIGGER `records_integrity` AFTER UPDATE ON `records` FOR EACH ROW SET 
NEW.epc=IFNULL(earnings/clicks,0);

同时遇到了以下错误:

MySQL said: #1362 - Updating of NEW row is not allowed in after trigger

我也尝试使用OLD,但是还是出现了错误。如果我使用BEFORE,那么如果我添加100次点击,它将使用之前的#点击来触发(对吧?)。

我应该怎么做才能实现这个功能?

编辑 - 这里是可能会在此上运行的查询示例:

UPDATE records SET clicks=clicks+100
//EPC should update automatically
2个回答

15

after 更新触发器中,您无法更新表中的行。

也许您想要类似于这样的东西:

CREATE TRIGGER `records_integrity` BEFORE UPDATE
ON `records`
FOR EACH ROW
    SET NEW.epc=IFNULL(new.earnings/new.clicks, 0);

编辑:

在触发器中,您可以访问OLDNEWOLD是记录中的旧值,NEW是新值。 在before触发器中,NEW值是写入表格的内容,所以您可以修改它们。 在after触发器中,NEW值已经被写入,因此无法进行修改。 我认为MySQL文档解释得很清楚。


@hellohellosharp . . . 当我看代码时,它似乎不是这样的。 ;) - Gordon Linoff
感谢您的更新——您的答案似乎有效。不过我有点困惑...在更新之前难道不会使用错误的点击次数和收益值吗? - kmoney12
@hellohellosharp . . . 这就是“旧”和“新”的区别。set使用的是“新”的值。 - Gordon Linoff
有道理...我会尽快接受你的答案。我想我不明白BEFORE语句如何知道NEW值。 - kmoney12
在SET语句之后如何使用WHERE id=id? - Kingsley
@KingsleyChew,你应该提出一个新问题作为问题,而不是评论。 - Gordon Linoff

0

也许你可以在那个事务中写两个单独的语句。

 update record set clicks=...

 update record set epc=...

或者你可以将它们放在一个函数里面,比如updateClick(),然后只需调用该函数。通过这种方式,如果需要的话,你可以轻松地修改你的逻辑。
将逻辑放在触发器中可能会导致调试和追踪变得不必要地复杂。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接