我正在尝试从多个表中删除。这是我的表格的样子
A_has_B ---- B ---- C_has_B
(many to many) (many to many)
我试图在B中删除A_has_B,B和C_has_B中的所有行。我使用带有innodb存储引擎的MySQL,其中为A_has_B定义了外键,而C_has_B引用了B中的ID。
我正试图像我这样执行删除:
DELETE A_has_B.*, C_has_B.*, B.*
FROM
A
join
B
on (B.B_id = A.B_id)
join
C
on (C.B_id = B.B_id)
where B.B_id IN(1,2, 4);
问题是当我执行查询时,mysql抱怨:
Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails (`db`.`C`, CONSTRAINT `fk_C` FOREIGN KEY (`B_id`) REFERENCES `B` (`B_id`) ON DELETE NO ACTION ON UPDATE NO)
我该如何解决这个问题?
答案 0 :(得分:30)
最简单的方法是从每个表中单独删除:
-- Remove all connections from A which reference
-- the B-rows you want to remove
DELETE FROM A_has_B
WHERE B_id IN (1,2,4);
-- Remove all connections from C which reference
-- the B-rows you want to remove
DELETE FROM C_has_B
WHERE B_id IN (1,2,4);
-- Finally remove the B-rows
DELETE FROM B
WHERE B_id IN (1,2,4);
MySQL还允许您在一个语句中从多个表中删除。但是没有办法控制删除的顺序。来自manual:
如果使用涉及有外键约束的InnoDB表的多表DELETE语句,MySQL优化器可能会按照与父/子关系不同的顺序处理表。在这种情况下,语句失败并回滚。相反,您应该从单个表中删除并依赖InnoDB提供的ON DELETE功能,以便相应地修改其他表。
答案 1 :(得分:9)
实际上,在MySQL中,您可以关闭对外键约束的检查
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
--your SQL statements
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
第一行的声明迫使MySQL服务器关闭外键检查,最后一行将重新打开(非常重要)。要牢记两件事:
答案 2 :(得分:3)
您可以在外键上指定“删除级联”。 删除父行时,mysql引擎将删除相关子表中的记录
答案 3 :(得分:0)
在单独的语句中删除它,它会起作用。