欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

mysql数据库ERROR#1442报错问题的解决方法

程序员文章站 2023-03-27 16:53:09
0x00 问题描述 在一个计算本月薪资的表中,我想要使得当基本工资,补贴出现变动时,自动更新本月总薪资的值 一开始我的操作是 CREATE DEFINER=`root`@...

0x00 问题描述

在一个计算本月薪资的表中,我想要使得当基本工资,补贴出现变动时,自动更新本月总薪资的值

一开始我的操作是

CREATE DEFINER=`root`@`localhost` TRIGGER `修改时总工资` 
AFTER UPDATE ON `payment` 
FOR EACH ROW 
UPDATE payment SET pay_total = NEW.pay_basic + pay_check +pay_refund WHERE pay_num = NEW.pay_num

结果报错

MySQL: Solution for ERROR 1442 (HY000): Can’t update table ‘xxx’ in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

这个报错的描述:“不能在存储函数或触发器中更新表,因为它已经被调用这个存储函数/触发器的语句所使用”

————

简单来说,就是你想要更新的这个表,正在更新,不能同时进行两个更新操作【这是我个人的理解,如有不当请指出】

0x01 解决问题

事实上,在使用after的情况下,如果对触发事件表进行操作,应该是都会报#1442的错误的。如果在其他表执行相应,则不会出现该错误。

那么我们只能用before了。


其实我们在这里可以猜测所谓的“after”和“before”的含义,它并不是完全意义上的“之后”和“之前”,也就是这里的“之前之后”实际上是【紧接着】而不是【另一条语句】

注:这个问题是在做课程设计时候发现的,期末繁忙期,没有太多时间查询mysql官方文档研究触发器的机制了,故这里放一下自己的猜测,日后再查文档


既然触发器是【紧接着】的操作,这里再扩展一下我的猜测,【紧接着】的触发器可以理解为“与我们执行的sql命令并在一起为一个复合sql命令”。所以使用了触发器后的结构可能是这样的:

//BEFORE
{
    触发器语句;
    sql命令;
}
//AFTER
{
    sql命令;
    触发器语句;
}

这样一来,为什么报错的原因便更加清晰了:你的操作都还没凉,哪来的NEW.(点)

接着这个思路,

我想到了这个操作

CREATE DEFINER=`root`@`localhost` TRIGGER `修改时总工资` 
BEFORE UPDATE ON `payment` 
FOR EACH ROW 
SET NEW.pay_total = NEW.pay_basic + NEW.pay_check + NEW.pay_refund

诶!是不是很简单?因为理解为复合语句,因此我们仅需要做一下简单的赋值不就可以了吗?