3

我有下表[页]:

pgid|pgname|pgorder
----+------+-------
  1 |Page#1|   1
  2 |Page#2|   2
  3 |Page#3|   3
  4 |Page#4|   4

列“pgorder”表示特定页面的位置。

我需要触发器,它会在删除一页记录后自动移动(减少)一个位置的剩余页面顺序。

因此,当我删除例如 pgid=2 时,表应如下所示:

pgid|pgname|pgorder
----+------+-------
  1 |Page#1|   1
  3 |Page#3|   2
  4 |Page#4|   3

这个 MySQL 触发器应该是什么样子的?

4

1 回答 1

3

您不能使用 DML 语句来修改触发触发器的同一个表。你得到这个错误:

ERROR 1442 (HY000): Can't update table 'pages' in stored function/trigger because 
it is already used by statement which invoked this stored function/trigger.

原因是它有无限循环的风险,或者至少是死锁。如果 DELETE 在触发触发器之前锁定了表,然后在触发器内执行请求锁定表的 UPDATE,则两者都无法继续。

请参阅https://dev.mysql.com/doc/refman/5.6/en/stored-program-restrictions.html

存储的函数或触发器不能修改已被调用函数或触发器的语句使用(用于读取或写入)的表。

正确的解决方案是分两步执行此任务:首先是 DELETE,然后是 UPDATE:

DELETE FROM pages WHERE pgorder = 3;
UPDATE pages SET pgorder = pgorder-1 WHERE pgorder > 3;

您可以在事务中执行这两个 DML 语句,以确保它们在您提交之前都成功,或者回滚事务。

于 2014-09-13T19:09:58.103 回答