mysql数据库ERROR#1442报错问题的解决方法
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
诶!是不是很简单?因为理解为复合语句,因此我们仅需要做一下简单的赋值不就可以了吗?
下一篇: C语言运算符入门讲解