如何解决错误 1442:无法更新 mysql 中存储的函数/触发器中的表 'tb_name'?

Posted

技术标签:

【中文标题】如何解决错误 1442:无法更新 mysql 中存储的函数/触发器中的表 \'tb_name\'?【英文标题】:How to solve error 1442 : Can`t update table 'tb_name' in stored fuction/trigger in mysql?如何解决错误 1442:无法更新 mysql 中存储的函数/触发器中的表 'tb_name'? 【发布时间】:2021-08-24 16:24:42 【问题描述】:
delimiter $$ 
   create trigger payment_mile_trigger
    after insert on PAYMENT
    for each row
    begin
    if @mileuse = 'all' then
        update customer
        set cust_usedmile = cust_usedmile + cust_currentmile
            and cust_currentmile = 0
        where customer.cust_id = new.cust_id;
    elseif @mileuse > 0 then
        update customer
        set cust_usedmile = cust_currentmile + @mileuse
            and cust_currentmile = cust_currentmile - @mileuse
        where customer.cust_id = new.cust_id;
    end if ;
   end $$
delimiter ;
delimiter $$ 
   create trigger Booking_trigger3
    before insert on Booking
    for each row
    begin
      declare pay_totalamount int;
      declare time_stamp timestamp;
      declare pay_type varchar(15);
      declare key_id int;
      declare cust_id int;
      
      set pay_totalamount = new.booking_totalamount;
      set time_stamp = current_timestamp();
      set pay_type = @paytype;
      set key_id = null;
      set cust_id = new.cust_id;
      
    if @mileuse = 'all' then
        insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id) 
        value ((select cust_currentmile from customer where customer.cust_id=cust_id),
        time_stamp, 'mile',key_id,cust_id);
        insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id) 
        value (pay_totalamount-(select cust_currentmile from customer where cust_id=cust_id),
        time_stamp, pay_type,key_id,cust_id);
    elseif @mileuse > 0 then
        insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id) 
        value (@mileuse,
        time_stamp, 'mile',key_id,cust_id);
        insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id) 
        value (pay_totalamount-@mileuse,
        time_stamp, pay_type,key_id,cust_id);
    else
      insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id) 
        value (pay_totalamount,time_stamp, pay_type,key_id,cust_id);
    end if;
   end $$
delimiter ;

我创建了两个触发器。

如果您在预订时使用里程付款,则其中一个触发器会在付款表中插入两个数据。 (支付里程,剩余金额通过其他支付方式支付)

另一个触发因素是扣除里程。 如果支付表中有里程支付的项目,则从客户表中扣除里程。

但我得到一个错误:

错误代码:1442。无法更新存储函数/触发器中的表“客户”,因为它已被调用此存储函数/触发器的语句使用。

我的猜测是这个问题是由于上述两个触发器的冲突造成的。这是因为一个是在里程用完的情况下从客户表中选择数据(里程),而另一个是从客户表中更新数据(里程)。

我发现了两个问题。 首先是里程不从客户表中扣除。

第二个问题是当我设置 @mileuse = 'all' 时,我得到与标题相同的错误。

我该如何解决这个问题?

【问题讨论】:

我已经编辑了内容以进一步阐述我发现的问题。 【参考方案1】:

我以稍微不同的方式解决了这个问题。

delimiter $$ 
   create trigger Booking_trigger3
    before insert on Booking
    for each row
    begin
      declare pay_totalamount int;
      declare time_stamp timestamp;
      declare pay_type varchar(15);
      declare key_id int;
      declare cust_id int;
      
      set pay_totalamount = new.booking_totalamount;
      set time_stamp = current_timestamp();
      set pay_type = @paytype;
      set key_id = null;
      set cust_id = new.cust_id;

    if @mileuse > 0 then
        insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id) 
        value (@mileuse,
        time_stamp, 'mile',key_id,cust_id);
        insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id) 
        value (pay_totalamount-@mileuse,
        time_stamp, pay_type,key_id,cust_id);
    else
      insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id) 
        value (pay_totalamount,time_stamp, pay_type,key_id,cust_id);
    end if;
   end $$
delimiter ;

我删除了“如果@mileuse = all then ...”

select @mileuse := '0';
select @mileuse := 
    (select cust_currentmile from customer
        where cust_id = @custid); # all mile pay 

我决定将变量一分为二。

这似乎不是一个基本的解决方案,但却是实现它的最佳方式。

【讨论】:

以上是关于如何解决错误 1442:无法更新 mysql 中存储的函数/触发器中的表 'tb_name'?的主要内容,如果未能解决你的问题,请参考以下文章

错误代码:1442。无法更新存储函数/触发器中的表“客户”,因为它已被调用此存储函数的语句使用

MySql 触发器删除同一张表中的子记录

1442 - Can't update table 'site' in stored functiontrigger because it is al

如何重写此 MySQL 查询,使其不会引发此错误:您无法在 FROM 子句中指定目标表 'crawlLog' 进行更新?

在 MySQL“删除前”中触发

为啥 Java 在最新的 JDK 更新后无法连接到 MySQL 5.7,应该如何解决? (ssl.SSLHandshakeException:没有适当的协议)