错误1452:无法添加或更新子行:外键约束失败

问题描述 投票:86回答:10

我在MySQL Workbench中创建了表,如下所示:

订单表:

CREATE TABLE Ordre (
  OrdreID   INT NOT NULL,
  OrdreDato DATE DEFAULT NULL,
  KundeID   INT  DEFAULT NULL,
  CONSTRAINT Ordre_pk PRIMARY KEY (OrdreID),
  CONSTRAINT Ordre_fk FOREIGN KEY (KundeID) REFERENCES Kunde (KundeID)
)
  ENGINE = InnoDB;

产品表:

CREATE TABLE Produkt (
  ProduktID          INT NOT NULL,
  ProduktBeskrivelse VARCHAR(100) DEFAULT NULL,
  ProduktFarge       VARCHAR(20)  DEFAULT NULL,
  Enhetpris          INT          DEFAULT NULL,
  CONSTRAINT Produkt_pk PRIMARY KEY (ProduktID)
)
  ENGINE = InnoDB;

和ORDER行:

CREATE TABLE Ordrelinje (
  Ordre         INT NOT NULL,
  Produkt       INT NOT NULL,
  AntallBestilt INT DEFAULT NULL,
  CONSTRAINT Ordrelinje_pk PRIMARY KEY (Ordre, Produkt),
  CONSTRAINT Ordrelinje_fk FOREIGN KEY (Ordre) REFERENCES Ordre (OrdreID),
  CONSTRAINT Ordrelinje_fk1 FOREIGN KEY (Produkt) REFERENCES Produkt (ProduktID)
)
  ENGINE = InnoDB;

所以当我尝试将值插入ORDRELINJE表时,我得到:

错误代码:1452。无法添加或更新子行:外键约束失败(srdjank.Ordrelinje,CONSTRAINT Ordrelinje_fk FOREIGN KEY(Ordre)REFERENCES OrdreOrdreID))

我已经看过关于这个主题的其他帖子,但没有运气。我在监督某事或知道该怎么做?

mysql mysql-error-1452
10个回答
126
投票

取自Using FOREIGN KEY Constraints

外键关系涉及保存中心数据值的父表,以及具有指向其父级的相同值的子表。 FOREIGN KEY子句在子表中指定。

如果父表中没有匹配的候选键值,它将拒绝任何尝试在子表中创建外键值的INSERT或UPDATE操作。

所以你的错误Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails本质上意味着,你试图在你的Ordrelinje表中添加一行,Ordre表中没有匹配的行(OrderID)。

您必须先将行插入Ordre表。


0
投票

这可以通过首先在Parent表中插入相应的记录来修复,然后我们可以在Child表的相应列中插入记录。还要检查列的数据类型和大小。它应该与父表列相同,即使引擎和排序规则也应该相同。试试这个!这就是我解决了我的问题。如果我错了,请纠正我。


28
投票

您正在进行此约束检查,因为ordre表没有在insert命令中提供的引用顺序ID。

要在ordrelinje中插入值,首先必须在ordre表中输入值,并在orderlinje表中使用相同的ordreID。

或者,您可以删除非null约束并在其中插入NULL值。


14
投票

您必须将子表中没有任何对应外键值的数据删除到父表主键。或者从子表中删除所有数据,然后在父表中插入与主键具有相同外键值的新数据。这应该工作。这里还有一个youtube video


10
投票

通常会发生此错误,因为我们在子表的引用字段中有一些值,这些值在父表的引用/候选字段中不存在。

有时,当我们将外键约束应用于现有表时,我们可能会收到此错误,其中已有数据。其他一些答案建议完全从子表中删除数据,然后应用约束。但是,当我们在子表中已经有工作/生产数据时,这不是一个选项。在大多数情况下,我们需要更新子表中的数据(而不是删除它们)。

现在,我们可以利用Left Join查找子表中的所有行,这些行在父表中没有匹配的值。以下查询(从其他答案中遗漏),将有助于获取那些不匹配的行:

SELECT child_table.* 
FROM child_table 
LEFT JOIN parent_table 
  ON parent_table.referenced_column = child_table.referencing_column 
WHERE parent_table.referenced_column IS NULL

现在,您通常可以执行以下一个(或多个)步骤来修复数据。

  1. 根据您的“业务逻辑”,您需要使用父表中的现有值更新/匹配这些不匹配的值。你有时可能需要设置它们null
  2. 删除具有不匹配值的这些行。
  3. 在父表中添加新行,对应于子表中的不匹配值。

修复数据后,我们可以使用ALTER TABLE语法应用外键约束。


6
投票

问题在于FOREIGN KEY约束。默认情况下(SET FOREIGN_KEY_CHECKS = 1)。 FOREIGN_KEY_CHECKS选项指定是否检查InnoDB表的外键约束。 MySQL - SET FOREIGN_KEY_CHECKS

我们可以在运行Query之前将外键检查设置为禁用。 Disable Foreign key

在运行查询之前执行其中一行,然后您可以成功运行查询。 :)

1)会议(推荐)

SET FOREIGN_KEY_CHECKS=0;

2)全球

SET GLOBAL FOREIGN_KEY_CHECKS=0;

1
投票

插入外键属性值时,首先验证属性类型以及父关系中的主键属性值,如果父关系中的值匹配,则可以轻松插入/更新子属性值。


1
投票

您应该将PRIMARY TABLE中的REFERENCES KEY中的数据添加到CHILD TABLE中的FOREIGN KEY 它意味着不要将随机数据添加到外键,只需使用可访问的主键中的数据

description of data in foreign key


0
投票

您的ORDRELINJE表使用外键约束ORDERconstraint Ordrelinje_fk foreign key(Ordre) references Ordre(OrdreID)表链接,根据该表Ordre int NOT NULL,ORDRELINJE列必须匹配Ordre int NOT NULL,表的任何ORDER列。

现在这里发生的是,当您在ORDRELINJE表中插入新行时,根据fk约束Ordrelinje_fk,如果ORDER存在与否,它正在检查OrdreID表,因为它与任何OrderId不匹配,编译器正在抱怨外键违反。这就是您收到此错误的原因。

外键是另一个表的主键,您可以在任何表中使用它来链接它们。此键由您在创建表时指定的外键约束绑定。对数据的任何操作都不得违反此约束。违反此约束可能会导致此类错误。

希望我说清楚。


0
投票

你应该在每个表中插入至少一个raw(你希望外键指向的那些)然后你可以插入或更新外键的值

© www.soinside.com 2019 - 2024. All rights reserved.