【问题标题】:MYSQL - Cannot update a parent row: a foreign key constraint failsMYSQL - 无法更新父行:外键约束失败
【发布时间】:2021-12-03 07:34:12
【问题描述】:

db-fiddle link

架构查询

-- 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,

参考 FIELD_TEST 的 ID 更改 GRAPH_FIELD_INFO_TEST ID,

我在 GRAPH_FIELD_INFO_TEST 中将其设置为级联。

但是,由于以下错误,它失败了。

如果我更改GRAPH的ID,它可以正常工作,

但只有更改了 FIELD_TEST 的 ID 后才能正常工作。

我可以知道错误的原因吗?

【问题讨论】:

    标签: mysql sql foreign-keys


    【解决方案1】:

    FIELD_TEST 表中的 field_idCHAR(50),但在 GRAPH_FIELD_INFO_TEST 表中它是 CHAR(32)

    CHAR 是一个固定长度类型,因此当您更新FIELD_TEST 表中的field_id 时,系统也会尝试使用CHAR(50) 更新引用列,这当然是失败(尽管实际值只有 32 个字符)。因此错误。将 field_id 列更改为在所有表中具有相同的长度...正如您的 db-fiddle 中所述,它适用于 GRAPH... 关系,因为所有表中的字段具有相同的长度。

    是的,当您插入数据时它会起作用,因为 'foobar' = 'foobar' 即使其中一个来自 CHAR(50) 列而另一个来自 CHAR(32) 列。因此,当您在子表中插入时,它可以在父表中找到相应的键。但是当父键长于子键时,它不能进行级联更新。

    【讨论】:

    • 我不敢相信我看不到这个。非常感谢!
    猜你喜欢
    • 2017-09-15
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 2019-02-03
    • 2017-07-20
    相关资源
    最近更新 更多