使用内部联接进行删除并触发引发错误:无法更新存储的函数/触发器中的表'table_b'

问题描述

为什么出现以下错误( 无法更新存储函数/触发器中的表'table_b',因为调用该存储函数/触发器的语句已使用该表 )我尝试使用内部联接删除后出现? 我可以解决吗?

DROP TABLE if exists table_b;
DROP TABLE if exists table_a;

CREATE TABLE table_a (
  id int auto_increment,name varchar(255) DEFAULT NULL,primary key (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

DROP TABLE if exists table_b;
CREATE TABLE table_b (
  id int auto_increment,id_table_a int NOT null,another_table_id int NOT null,foreign key (id_table_a) references table_a(id),primary key (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

DELIMITER $$
drop trigger if exists tg_test$$
create trigger tg_test before delete on table_a for each row
begin
  delete from table_b where id_table_a = OLD.id;
end$$

DELIMITER ;

insert into table_a(name) values('t-a');
insert into table_b(name,id_table_a,another_table_id) values('t-b',1,23);

-- Error Can't update table 'table_b' in stored function/trigger because it is already used by statement which invoked this stored function/trigger
-- in any of this two lines
delete table_a from table_a inner join table_b on table_b.id_table_a = table_a.id where another_table_id = 23;
delete from table_a where id in (select id_table_a from table_b where another_table_id = 23);

-- Success
delete from table_a where id = 1;

解决方法

我在这里看不到触发点。只需在外键的声明中添加on delete cascade选项即可实现所需的功能:

CREATE TABLE table_b (
  id int auto_increment,name varchar(255) DEFAULT NULL,id_table_a int NOT null,another_table_id int NOT null,foreign key (id_table_a) references table_a(id) on delete cascade,primary key (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

现在无论何时从table_a删除记录,子记录(由外键定义指定)都将从table_b中删除。

有了这个设置(没有触发器),您的delete语句都可以正常运行。我实际上会使用exists而不是joinin,但这主要取决于口味:

delete from table_a 
where exists( 
    select 1 
    from table_b b 
    where b.id_table_a = table_a.id and b.another_table_id = 23
);

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...