📜  mysql 无法删除或更新父行 - SQL (1)

📅  最后修改于: 2023-12-03 15:17:47.941000             🧑  作者: Mango

MySQL无法删除或更新父行 - SQL

在MySQL中,当一个父行被其他行引用时,删除或更新父行可能会失败,因为存在外键约束。这个问题被称为“无法删除或更新父行”。

本文将介绍如何处理这种问题,并提供一些常见的解决方案。

原因

当一个表中的一个列被设置为外键时,它会指向另一个表中的一个列。这个列被称为参照列,它在另一个表中是主键或唯一索引。

当想要从参照列所在的表中删除或更新一行时,如果该行在其他表中作为外键存在引用关系,则会出现问题。例如:

CREATE TABLE parent (
  id INT NOT NULL PRIMARY KEY
);

CREATE TABLE child (
  id INT NOT NULL PRIMARY KEY,
  parent_id INT REFERENCES parent(id)
);

INSERT INTO parent (id) VALUES (1);

INSERT INTO child (id, parent_id) VALUES (1, 1);

在上面的例子中,child表中的parent_id列是一个外键,它参照了parent表中的id列。如果想从parent表中删除或更新id=1的行,由于存在外键约束,将无法成功执行。

解决方案
1. 删除或更新引用行

最简单的解决方案是删除或更新引用父行的子行。在上面的例子中,可以先删除child表中引用了parent表中id=1的行,然后再删除parent表中id=1的行:

DELETE FROM child WHERE parent_id = 1;
DELETE FROM parent WHERE id = 1;
2. 修改外键约束

在某些情况下,可能需要保留子行,但仍希望删除或更新父行。这时,可以修改外键约束,使其可以对父行进行删除或更新操作。

在上面的例子中,可以使用ON DELETE CASCADE选项,将自动删除child表中引用了parent表中id=1的行:

CREATE TABLE child (
  ...
  parent_id INT REFERENCES parent(id) ON DELETE CASCADE
);

同样,也可以使用ON UPDATE CASCADE选项,使子行在更新父行时也随之更新。

3. 关闭外键约束

在必须删除或更新父行而无法执行前两种解决方案时,可以考虑关闭外键约束,执行操作后再打开约束。关闭约束后,可以执行对父行的操作,但同时也必须自行维护数据完整性。

在上面的例子中,可以使用以下语句关闭外键约束,删除parent表中id=1的行,然后再打开外键约束并手动更新child表中的数据:

SET FOREIGN_KEY_CHECKS = 0;
DELETE FROM parent WHERE id = 1;
SET FOREIGN_KEY_CHECKS = 1;

UPDATE child SET parent_id = NULL WHERE parent_id = 1;
总结

在MySQL中,当存在外键约束时,删除或更新父行可能会失败。本文介绍了三种解决方案:删除或更新引用行、修改外键约束和关闭外键约束。根据实际情况选择适合自己的解决方案,并注意维护数据完整性。