【问题标题】:How to avoid circular Trigger dependencies in MySQL如何避免 MySQL 中的循环触发器依赖
【发布时间】:2012-03-23 03:14:08
【问题描述】:

我在 MySQL 中使用触发器有一点问题。

假设我们有 2 个表:

  • 表A
  • 表B

还有 2 个触发器:

  • TriggerA:在 TableA 上删除并更新 TableB 时触发
  • TriggerB:在 TableB 上删除并在 TableA 中删除时触发

问题是当我删除 TableB 中的一些行时,TriggerB 触发并删除 TableA 中的一些元素,然后 TriggerA 触发并尝试更新 TableB。

它失败了,因为 TriggerA 试图更新 TableB 中被删除的一些行。

如何避免这种循环依赖?

这两个触发器都没有用,所以我不知道我该怎么做才能解决这个问题。

【问题讨论】:

  • 您能否展示一些有关这些表的数据,并准确告诉我们触发器的作用以及它们是如何定义的?
  • @kensou:您能否向我们展示您的架构以及这两个触发器应该实现的目标?可能可以对其进行规范化以避免循环触发器(或全部)。

标签: mysql triggers circular-dependency


【解决方案1】:

尝试使用变量。

第一次触发:

CREATE TRIGGER trigger1
  BEFORE DELETE
  ON table1
  FOR EACH ROW
BEGIN
  IF @deleting IS NULL THEN
    SET @deleting = 1;
    DELETE FROM table2 WHERE id = OLD.id;
    SET @deleting = NULL;
  END IF;
END

第二次触发:

CREATE TRIGGER trigger2
  BEFORE DELETE
  ON table2
  FOR EACH ROW
BEGIN
  IF @deleting IS NULL THEN
    SET @deleting = 1;
    DELETE FROM table1 WHERE id = OLD.id;
    SET @deleting = NULL;
  END IF;
END

还有额外的 AFTER DELETE 触发器:

CREATE TRIGGER trigger3
  AFTER DELETE
  ON table1
  FOR EACH ROW
BEGIN
  SET @deleting = NULL;
END

CREATE TRIGGER trigger4
  AFTER DELETE
  ON table2
  FOR EACH ROW
BEGIN
  SET @deleting = NULL;
END

【讨论】:

  • 可能值得编写 BEFORE DELETE 触发器来删除记录,并编写 AFTER DELETE 触发器来将 @deleting 变量重置为 NULL。我修改了答案。
  • 为什么我们需要触发器 3 和 4 ?我们不是在删除 BEFORE DELETE 触发器后将 @deleting 重置为 NULL 吗?
  • 另外,您能否描述一下deleting 应该在哪里声明,以便所有触发器都可以访问它?
  • @KennetCeleste 在 MySQL 中以 @ 开头的变量在每个会话中都是全局的,所以 SET @deleting = 1; 是它的定义。 select @deleting 在定义之前将产生 null
  • 所以这种方法不适用于远程服务器,对吧?
猜你喜欢
  • 2013-02-06
  • 1970-01-01
  • 2012-02-15
  • 2013-04-02
  • 2012-08-10
  • 1970-01-01
  • 2016-08-09
  • 2023-03-11
相关资源
最近更新 更多