我的桌面上有一个自引用外键约束。因为我正在转换架构,所以我想将现有数据复制到一个具有(或多或少)相同结构的新表中:
CREATE TABLE test(
id INT NOT NULL PRIMARY KEY,
parent INT,
FOREIGN KEY (parent) REFERENCES test(id)
);
CREATE TABLE copy(
id INT NOT NULL PRIMARY KEY,
parent INT,
FOREIGN KEY (parent) REFERENCES copy(id)
);
然而,当inserting the data:
时INSERT INTO copy(id, parent) SELECT id, parent FROM test;
MySQL给了我常见的完整性错误:
Error Code: 1452. Cannot add or update a child row:
a foreign key constraint fails (`test`.`copy`, CONSTRAINT `copy_ibfk_1`
FOREIGN KEY (`parent`) REFERENCES `copy` (`id`))
似乎MySQL在插入每一行后检查约束,而不是在整个插入后检查它。完全相同的示例works fine in PostgreSQL。
有没有其他方法可以插入这些数据,还是我坚持这样做两步呢?
INSERT INTO copy(id) SELECT id FROM test;
UPDATE copy
JOIN test ON test.id = copy.id
SET copy.parent = test.parent;
答案 0 :(得分:1)
您可以使用
SET FOREIGN_KEY_CHECKS=0;
在INSERT和之前
SET FOREIGN_KEY_CHECKS=1;
禁用外键约束检查后,您不必担心插入的顺序:
的文档FOREIGN_KEY_CHECKS
如果设置为1(默认值),InnoDB表的外键约束 检查。如果设置为0,则忽略此类约束。 [...]通常 在正常操作期间启用此设置,以强制执行 参照完整性。禁用外键检查可能很有用 以不同于所需的顺序重新加载这些表 他们的父母/子女关系。请参见第14.6.6节“InnoDB和 外键约束“。 [...]
注意强>
将foreign_key_checks设置为1不会触发扫描 现有的表格数据。因此,行添加到表中的同时 foreign_key_checks = 0将不会被验证是否一致。
CREATE TABLE test(
id INT NOT NULL PRIMARY KEY,
parent INT,
FOREIGN KEY (parent) REFERENCES test(id)
);
CREATE TABLE copy(
id INT NOT NULL PRIMARY KEY,
parent INT,
FOREIGN KEY (parent) REFERENCES copy(id)
);
INSERT INTO test(id, parent) VALUES(1, null);
INSERT INTO test(id, parent) VALUES(2, 1);
INSERT INTO test(id, parent) VALUES(3, null);
INSERT INTO test(id, parent) VALUES(4, 2);
UPDATE test SET parent=3 WHERE id=1;
SET FOREIGN_KEY_CHECKS=0;
-- Success with MySQL
INSERT INTO copy(id, parent) SELECT id, parent FROM test;
SET FOREIGN_KEY_CHECKS=1;
您的更新小提琴:http://sqlfiddle.com/#!2/ae623/1