MYSQL - 无法更新父行:外键约束失败
MYSQL - Cannot update a parent row: a foreign key constraint fails
架构查询
-- GRAPH INFO TABLE--------------------------------------------------------------
CREATE TABLE GRAPH
(
graph_id CHAR(32) NOT NULL PRIMARY KEY,
name VARCHAR(1024) NOT NULL
);
INSERT INTO GRAPH set graph_id = MD5('graph1'),
name = 'graph1';
INSERT INTO GRAPH set graph_id = MD5('graph2'),
name = 'graph2';
INSERT INTO GRAPH set graph_id = MD5('graph3'),
name = 'graph3';
-- FIELD INFO TABLE--------------------------------------------------------------
CREATE TABLE FIELD_TEST
(
field_id CHAR(50) NOT NULL PRIMARY KEY,
name VARCHAR(500) NOT NULL
);
INSERT INTO FIELD_TEST set field_id = MD5('field1'),
name = 'field1';
INSERT INTO FIELD_TEST set field_id = MD5('field2'),
name = 'field2';
INSERT INTO FIELD_TEST set field_id = MD5('field3'),
name = 'field3';
-- GRAPH FIELD RELATION TABLE-----------------------------------------------------
CREATE TABLE GRAPH_FIELD_INFO_TEST
(
field_id CHAR(32) NOT NULL,
graph_id CHAR(32) NOT NULL,
PRIMARY KEY (graph_id, field_id),
CONSTRAINT GRAPH_FIELD_INFO_TEST_FIELD_field_id_fk
FOREIGN KEY (field_id) REFERENCES FIELD_TEST (field_id)
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT GRAPH_FIELD_INFO_TEST_GRAPH_STORAGE_graph_id_fk
FOREIGN KEY (graph_id) REFERENCES GRAPH (graph_id)
ON UPDATE CASCADE ON DELETE CASCADE
);
INSERT INTO GRAPH_FIELD_INFO_TEST set field_id = MD5('field1'),
graph_id = MD5('graph1');
INSERT INTO GRAPH_FIELD_INFO_TEST set field_id = MD5('field2'),
graph_id = MD5('graph2');
INSERT INTO GRAPH_FIELD_INFO_TEST set field_id = MD5('field3'),
graph_id = MD5('graph3');
更新查询
UPDATE FIELD_TEST
SET name = 'new field1',
field_id = MD5('new field1')
WHERE field_id = MD5('field1');
错误
Query Error: Error: ER_ROW_IS_REFERENCED_2: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`GRAPH_FIELD_INFO_TEST`, CONSTRAINT `GRAPH_FIELD_INFO_TEST_FIELD_field_id_fk` FOREIGN KEY (`field_id`) REFERENCES `FIELD_TEST` (`field_id`) ON DELETE CASCADE ON UPDATE CASCADE)
如果我更改 FIELD_TEST 的 ID,
修改GRAPH_FIELD_INFO_TEST ID 参考FIELD_TEST,
的ID
我在GRAPH_FIELD_INFO_TEST中设置为级联。
但是,由于以下错误,它失败了。
如果我更改GRAPH的ID,它可以正常工作,
但只有更改FIELD_TEST的ID才能正常工作
请问错误原因?
你的 FIELD_TEST
table 中的 field_id
是 CHAR(50)
,但你的 GRAPH_FIELD_INFO_TEST
table 中的 CHAR(32)
].
CHAR
是一个定长类型,所以当你在FIELD_TEST
table系统中更新field_id
还尝试使用 CHAR(50)
更新引用列,这当然会失败(尽管实际值只有 32 个字符)。因此错误。将 field_id
列更改为在所有 table 中具有相同的长度...如您的 db-fiddle 中所述,它适用于 GRAPH...
关系,因为所有字段table长度相同。
是的,它在您插入数据时起作用,因为 'foobar' = 'foobar'
即使其中一个来自 CHAR(50)
列而另一个来自 CHAR(32)
列。所以当你在你的 child table 中插入时,它可以在 parent table 中找到相应的键。但是当 parent 键长于 child.
时,它不能进行级联更新
架构查询
-- GRAPH INFO TABLE--------------------------------------------------------------
CREATE TABLE GRAPH
(
graph_id CHAR(32) NOT NULL PRIMARY KEY,
name VARCHAR(1024) NOT NULL
);
INSERT INTO GRAPH set graph_id = MD5('graph1'),
name = 'graph1';
INSERT INTO GRAPH set graph_id = MD5('graph2'),
name = 'graph2';
INSERT INTO GRAPH set graph_id = MD5('graph3'),
name = 'graph3';
-- FIELD INFO TABLE--------------------------------------------------------------
CREATE TABLE FIELD_TEST
(
field_id CHAR(50) NOT NULL PRIMARY KEY,
name VARCHAR(500) NOT NULL
);
INSERT INTO FIELD_TEST set field_id = MD5('field1'),
name = 'field1';
INSERT INTO FIELD_TEST set field_id = MD5('field2'),
name = 'field2';
INSERT INTO FIELD_TEST set field_id = MD5('field3'),
name = 'field3';
-- GRAPH FIELD RELATION TABLE-----------------------------------------------------
CREATE TABLE GRAPH_FIELD_INFO_TEST
(
field_id CHAR(32) NOT NULL,
graph_id CHAR(32) NOT NULL,
PRIMARY KEY (graph_id, field_id),
CONSTRAINT GRAPH_FIELD_INFO_TEST_FIELD_field_id_fk
FOREIGN KEY (field_id) REFERENCES FIELD_TEST (field_id)
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT GRAPH_FIELD_INFO_TEST_GRAPH_STORAGE_graph_id_fk
FOREIGN KEY (graph_id) REFERENCES GRAPH (graph_id)
ON UPDATE CASCADE ON DELETE CASCADE
);
INSERT INTO GRAPH_FIELD_INFO_TEST set field_id = MD5('field1'),
graph_id = MD5('graph1');
INSERT INTO GRAPH_FIELD_INFO_TEST set field_id = MD5('field2'),
graph_id = MD5('graph2');
INSERT INTO GRAPH_FIELD_INFO_TEST set field_id = MD5('field3'),
graph_id = MD5('graph3');
更新查询
UPDATE FIELD_TEST
SET name = 'new field1',
field_id = MD5('new field1')
WHERE field_id = MD5('field1');
错误
Query Error: Error: ER_ROW_IS_REFERENCED_2: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`GRAPH_FIELD_INFO_TEST`, CONSTRAINT `GRAPH_FIELD_INFO_TEST_FIELD_field_id_fk` FOREIGN KEY (`field_id`) REFERENCES `FIELD_TEST` (`field_id`) ON DELETE CASCADE ON UPDATE CASCADE)
如果我更改 FIELD_TEST 的 ID,
修改GRAPH_FIELD_INFO_TEST ID 参考FIELD_TEST,
的ID我在GRAPH_FIELD_INFO_TEST中设置为级联。
但是,由于以下错误,它失败了。
如果我更改GRAPH的ID,它可以正常工作,
但只有更改FIELD_TEST的ID才能正常工作
请问错误原因?
你的 FIELD_TEST
table 中的 field_id
是 CHAR(50)
,但你的 GRAPH_FIELD_INFO_TEST
table 中的 CHAR(32)
].
CHAR
是一个定长类型,所以当你在FIELD_TEST
table系统中更新field_id
还尝试使用 CHAR(50)
更新引用列,这当然会失败(尽管实际值只有 32 个字符)。因此错误。将 field_id
列更改为在所有 table 中具有相同的长度...如您的 db-fiddle 中所述,它适用于 GRAPH...
关系,因为所有字段table长度相同。
是的,它在您插入数据时起作用,因为 'foobar' = 'foobar'
即使其中一个来自 CHAR(50)
列而另一个来自 CHAR(32)
列。所以当你在你的 child table 中插入时,它可以在 parent table 中找到相应的键。但是当 parent 键长于 child.