【问题标题】:Delete from a table after update in another table causes an error in mysql在另一个表中更新后从一个表中删除导致mysql中的错误
【发布时间】:2018-12-15 05:32:53
【问题描述】:

我在 MySQL 数据库中有两个表:“users”表中的“users”和“subscription”,每个用户都有一个 subscriptionID,它是“subscriptions”中一行的 ID 或 NULL。我需要在“用户”上创建一个更新触发器,以删除“订阅”中将订阅 ID 的新值设置为空的行。

这是我的触发器:

CREATE TRIGGER `trg_DeleteSubscriptions` AFTER UPDATE ON `users`
FOR EACH ROW IF (NEW.subscriptionID <=> NULL) THEN 
DELETE FROM subscriptions s WHERE s.subscriptionID = OLD.subscriptionID; 
END IF

创建触发器没有问题,但是我有一个执行此查询的递归事件:

UPDATE users SET AccountState = 2, subscriptionID = null WHERE UserID IN
(SELECT * from (SELECT u.UserID FROM users u INNER JOIN subscriptions a ON
u.subscriptionID = a.subscriptionID WHERE a.EndDate < CURRENT_TIMESTAMP) as c) 

并导致错误:#1442 - 无法更新存储函数/触发器中的表“订阅”,因为它已被调用此存储函数/触发器的语句使用。

(我知道(select * from (select ..) as c) 的查询很奇怪,但那是为了解决另一个我无法更新的问题 'users' 表,因为它在子查询中使用,通过创建一个 别名/临时表)

我不明白是什么问题,因为触发器是从“用户”表中调用的,而删除是在“订阅”中进行的??

更新:我很确定问题是由事件的查询而不是触发器本身引起的,因为我用那个简单的查询'UPDATE users SET SubscriptionID = null WHERE UserID = 24 进行了测试,并且触发器正确执行而没有错误...

非常感谢!

【问题讨论】:

  • 样本数据和期望的结果真的很有帮助。
  • 好吧,假设用户 #1 的订阅 ID #5,订阅 #5 的结束日期为 2018-07-04 16:29:28。该查询应该将“null”设置为我们用户 #1 的订阅 ID(因为 EndDate

标签: mysql sql triggers sql-delete mysql-error-1442


【解决方案1】:

这是 MySQL 中记录的限制。

引用表 subscriptions 的 SQL 语句导致触发触发器。

所以不允许触发器修改subscriptions表的内容。

如果触发器尝试对subscriptions 表应用更改,MySQL 会引发错误。

MySQL 参考手册中记录了此限制。

【讨论】:

  • 谢谢!你知道我可以做些什么来实现我想要的吗?
  • 我可以通过创建和使用视图或临时表而不是我的子查询来解决这个问题吗??
  • 如果我们需要使用触发器,那么我们需要从导致触发器被触发的语句中删除对subscriptions 表的引用。我们可以创建一个临时表,并使用来自订阅的查询填充该表,然后在 UPDATE 语句中引用该临时表。但不清楚为什么我们需要使用触发器来执行操作。我的偏好是避免触发,并在与 UPDATE 语句相同的上下文中执行 DELETE 操作。
  • 谢谢!我们选择创建一个触发器,因为在应用程序中有几个地方我们将 null 设置为订阅(不仅仅是在事件中),我们希望自动删除“订阅”中的行,而不是每次编写两个查询
猜你喜欢
  • 2012-09-10
  • 2023-03-03
  • 2018-06-11
  • 1970-01-01
  • 2011-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-02
相关资源
最近更新 更多