无法更新在AFTER INSERT中执行触发器的表

时间:2012-02-10 11:57:07

标签: mysql triggers

我正在运行MySQL 5.5.9和InnoDB。

我尝试创建一个版本化的表,其中current字段指示记录是否是最新版本。类似的东西:

| autonumber | id | name | current
| 1          | 1  | Yes  | 0
| 2          | 1  | No   | 1

无论如何,我过去在MSSQL中经常通过AFTER INSERT触发器执行此操作,该触发器将具有相同ID的所有记录更新为current = 0。所以我们进入MySQL:

DELIMITER |

CREATE TRIGGER TRIGGER_Products_UpdateEarlierVersions AFTER INSERT ON Products
FOR EACH ROW BEGIN
    UPDATE Products
    SET current = 0
    WHERE   id = new.id
        AND current = 1
        AND autonumber <> new.autonumber;
END;
|

这样运行正常,但插入记录时:

insert into Products (id, name)
values (1, "Hello SO!");

我收到以下错误:

  

错误代码:1442。无法更新存储函数/触发器中的表'Products',因为它已被调用此存储函数/触发器的语句使用。

有没有办法解决这个问题?

4 个答案:

答案 0 :(得分:3)

从这里采取http://forums.mysql.com/read.php?99,122354,122505#msg-122505

  

当你插入一条记录时,mysql正在做一些锁定的东西。你不能   插入/更新/删除您插入的同一个表的行..因为   然后触发器会一次又一次地调用..结束于a   递归

答案 1 :(得分:1)

当你插入一条记录时,mysql正在做一些锁定的东西。你不能插入/更新/删除你插入的同一个表的行..因为那时触发器会一次又一次地调用..最后是一个递归

我曾经遇到过这个问题。我删除了更新命令。所以,试试这个:

DELIMITER |

CREATE TRIGGER TRIGGER_Products_UpdateEarlierVersions AFTER INSERT ON Products
FOR EACH ROW BEGIN

    SET current = 0
    WHERE   id = new.id
        AND current = 1
        AND autonumber <> new.autonumber;
END;
|

我认为这会奏效

答案 2 :(得分:0)

在MySQL中,无法更新在触发器中为其创建触发器的表('Products')。

根据MySQL文档,生成此错误是为了防止无限递归:当UPDATE发生时,触发器运行并更新表,此触发器UPDATE导致触发器再次运行,并再次运行,最后再次运行无限循环。

答案 3 :(得分:0)

这是5岁,但是我遇到了与OP相同的问题,最终到了这里,跟随@Sergey Benner链接到forum.mysql.com,并在Re: Can't update table 'tbl' in stored function/trigger...找到了以下内容:

我知道这是一篇过时的文章,但我偶然发现了答案,并认为我会分享。在插入/更新期间,您可以访问NEW对象,该对象包含所涉及表中的所有字段。如果在插入/更新之前进行编辑,然后在新对象中编辑要更改的字段,它将成为调用语句的一部分,而不是单独执行(消除递归) 例如。

在测试更新之前创建触发测试

每行

设置NEW.updateTime = NOW();

对于OP而言,可悲的是,该帖子是2008年3月18日发布的,比此帖子早很多年了。我猜想其他回答的成员还没有深入到forum.mysql线程中去发现这一点。该论坛的演讲非常不友好-StackOverflow绝对有规律。

我已经在我的上下文中对其进行了测试,并且效果很好。我讨厌被称为“触发-快乐”,但是如果帽子合适的话...