如何处理触发器中的碰撞问题?

Posted

技术标签:

【中文标题】如何处理触发器中的碰撞问题?【英文标题】:How can I handle collision issue in Triggers? 【发布时间】:2017-11-01 01:23:10 【问题描述】:

我在这样的表上有一个触发器 (更新前)

UPDATE contact_us SET updated_at = unix_timestamp() WHERE id = new.id

当我使用 phpMyadmin 更新该表的一行时,它会抛出此错误:

为了看得更清楚:

#1442 - 无法更新存储函数/触发器中的表“contact_us”,因为它已被调用此存储函数/触发器的语句使用。

我该如何解决这个问题?

【问题讨论】:

也许也显示触发器? @FMashiro Ther you go 显示存储过程? @Ravi 我没有! 我认为您正在创建一个无限循环,因为您的触发器与您尝试运行的 SQL 语句相同。所以,触发器运行,因为它运行,它也调用自己,等等...... 【参考方案1】:

    首先,此功能根本不需要触发器,只需使用带有automatic initialisation 的时间戳或日期时间字段即可。所以,定义updated_at如下:

    updated_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    

    如果您出于某种原因坚持使用触发器,即使那样,也不要使用单独的 update 语句来更新定义触发器的同一个表,因为这是不行的(无限循环)。使用NEW关键字访问新建记录的字段,修改字段内容:

    set NEW.updated_at = unix_timestamp();
    

【讨论】:

当行创建而不是更新时,您的第一种方法将起作用。 @stack 然后按照文档建议将ON UPDATE CURRENT_TIMESTAMP 添加到字段定义中。我将其添加到答案中。 听起来不错,但我现在如何为updated_at 行添加ON UPDATE CURRENT_TIMESTAMP?我的意思是目前该表已创建。我需要alter 吗? @stack 好吧,你可以通过说 abracadabra 来尝试,但可能一个 alter table 就可以了。使用您最喜欢的 mysql 管理器 GUI 来编辑字段定义。 好的,我在 phpMyadmin 中找到了一个选项,它可以为我做到这一点。但是该列的数据类型是int(11),我需要在其中存储unix_timestamp()(这是一个秒序列),而不是CURRENT_TIMESTAMP。你有什么主意吗?顺便点赞

以上是关于如何处理触发器中的碰撞问题?的主要内容,如果未能解决你的问题,请参考以下文章

您如何处理深度链接插件中的简历场景?

如何处理 ERD(表)设计中的“或”关系?

如何处理 Android 运行时权限中的“不再询问”复选框?

我应该如何处理 mysql 触发器中字段列表中未知的“Col_name”列?

自动布局和编程约束:如何处理多次触发的 updateConstraints?

SVN触发构建后如何处理来自Teamcity服务器本身的api