创建MySQL插入触发器遇报错:无法更新触发表staff的问题求助
触发器更新表时出现递归调用错误
问题描述
我在给staff表创建插入触发器时遇到问题:需求是插入数据时,如果PLACA字段值≥3000,就把它替换成0,但触发了错误:Can't update table 'staff' in stored function/trigger because it is already used by statement which invoked this stored function/trigger
表结构:
CREATE TABLE `staff` ( `ID` int(11) NOT NULL, `NAZWISKO` varchar(50) DEFAULT NULL, `PLACA` float DEFAULT NULL )
我写的触发器代码:
BEGIN IF new.placa >= 3000 THEN UPDATE staff SET new.placa = 0; END IF; END
我怀疑是递归问题,但刚接触触发器,想知道具体原因和解决办法。
问题原因
你猜的没错,确实是递归触发导致的错误。当你在触发器里执行UPDATE staff语句时,这个操作会再次触发同一张表的触发器(因为修改了表数据),形成无限递归,MySQL为了防止这种死循环直接抛出了错误。而且根本不需要用UPDATE语句修改即将插入的行——触发器里的NEW对象就是待插入的记录,直接修改它的字段值即可,完全没必要额外执行更新表的操作。
正确的触发器写法
你需要使用BEFORE INSERT类型的触发器(在数据插入到表之前触发),直接修改NEW.placa的值,不需要执行UPDATE:
DELIMITER // CREATE TRIGGER staff_before_insert BEFORE INSERT ON staff FOR EACH ROW BEGIN IF NEW.placa >= 3000 THEN SET NEW.placa = 0; END IF; END // DELIMITER ;
补充说明
BEFORE INSERT触发器会在数据真正写入表之前触发,此时修改NEW对象的字段值,最终插入到表中的就是修改后的值。- 避免使用
UPDATE操作,既解决了递归触发的问题,又提升了效率——直接修改待插入的记录,不用先插入再更新。
内容的提问来源于stack exchange,提问作者Dziki Jędrek
相关产品推荐
相关产品推荐

