如何处理触发器中的碰撞问题?
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
。你有什么主意吗?顺便点赞以上是关于如何处理触发器中的碰撞问题?的主要内容,如果未能解决你的问题,请参考以下文章
如何处理 Android 运行时权限中的“不再询问”复选框?
我应该如何处理 mysql 触发器中字段列表中未知的“Col_name”列?