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

Tom*_*Tom 165 mysql

表格1

+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| UserID   | int(11)     | NO   | PRI | NULL    | auto_increment |
| Password | varchar(20) | NO   |     |         |                |
| Username | varchar(25) | NO   |     |         |                |
| Email    | varchar(60) | NO   |     |         |                |
+----------+-------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

表2

+------------------+--------------+------+-----+---------+----------------+
| Field            | Type         | Null | Key | Default | Extra          |
+------------------+--------------+------+-----+---------+----------------+
| UserID           | int(11)      | NO   | MUL |         |                |
| PostID           | int(11)      | NO   | PRI | NULL    | auto_increment |
| Title            | varchar(50)  | NO   |     |         |                |
| Summary          | varchar(500) | NO   |     |         |                |
+------------------+--------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

错误:

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: 
Cannot add or update a child row: a foreign key constraint fails 
(`myapp/table2`, CONSTRAINT `table2_ibfk_1` FOREIGN KEY (`UserID`) 
REFERENCES `table1` (`UserID`)) 
Run Code Online (Sandbox Code Playgroud)

我做错了什么?我阅读http://www.w3schools.com/Sql/sql_foreignkey.asp,我看不出有什么问题.

Bri*_*oll 220

您收到此错误是因为您尝试根据当前存储的值将行添加/更新table2为该UserID字段没有有效值table1.如果您发布更多代码,我可以帮助您诊断具体原因.

  • 不确定downvote是为了什么; 我的回答是完全有效和正确的. (12认同)
  • 如果是这样的话,很可能是0,用Null替换它 (5认同)

小智 120

这意味着您正在尝试插入不存在table2UserIDtable1.


小智 98

一个简单的hack可以是在对表执行任何操作之前禁用外键检查.只需查询

SET FOREIGN_KEY_CHECKS=0
Run Code Online (Sandbox Code Playgroud)

这将禁用与任何其他表的外键匹配.完成表后再次启用它

SET FOREIGN_KEY_CHECKS=1
Run Code Online (Sandbox Code Playgroud)

这对我很有用.

  • @SachinfromPune只需添加SET FOREIGN_KEY_CHECKS = 0; 在mysql文件启动时,SET FOREIGN_KEY_CHECKS = 1;在mysql文件末尾,重新导入数据 (2认同)
  • 这不是有问题吗?你失去了参照完整性,对吧? (2认同)

Nic*_*oic 41

我发现了另一个奇怪的情况:如果您不小心从InnoDB表创建了一个外键到MyISAM表,MySQL会在插入时抛出此错误,即使数据有效也是如此.

http://nick.zoic.org/art/mysql-foreign-key-error/

  • 是的,我也有同样的问题。两个表应该是InnoDB! (2认同)
  • 我有同样的问题,谢谢你的提示.这里有关于如何将表从MyISAM转换为InnoDB的MySQL文档的链接https://dev.mysql.com/doc/refman/5.7/en/converting-tables-to-innodb.html TLDR:ALTER TABLE table_name ENGINE = InnoDB ; (2认同)

Jus*_*tin 15

你得到这个错误,因为有一些table2.UserID不存在的值int table1.UserID(我猜你table2.UserID在创建这个外键之前已经手动设置了值).
此场景的一个示例:table1.UserID获取值1,2,3并table2.UserID获取值4(通过手动添加).所以,当你犯了一个外键,他们无法找到UserID = 4table1和错误会ocurse.
要修复此错误,只需UserID = 4从中删除table2或者您可以清空它们,然后创建外键和.
祝好运!


小智 15

这花了我一段时间才弄明白。简单地说,引用另一个表的表中已经有数据,而父表中不存在其一个或多个值。

例如表2有以下数据:

UserID    PostID    Title    Summary
5         1         Lorem    Ipsum dolor sit
Run Code Online (Sandbox Code Playgroud)

表格1

UserID    Password    Username    Email
9         ********    JohnDoe     john@example.com
Run Code Online (Sandbox Code Playgroud)

如果您尝试 ALTER table2 并添加外键,则查询将失败,因为 Table1 中不存在 UserID=5。


Att*_*que 10

如果在表2中创建外键之前在表1中插入了一行,则会出现外键约束错误,因为表1中的自动增量值为2,表2中为1.要解决此问题,您必须截断表1并将自动增量值设置回1.然后可以添加表2.


Ama*_*rya 6

确保已将数据库引擎设置为InnoDB,因为在MyISAM中不支持外键和事务

  • 更改表 my_table 引擎 = InnoDB; (2认同)

Bla*_*tix 6

我遇到了同样的问题,解决方案很简单.

您正尝试在子表中添加父表中不存在的ID .

检查得好,因为InnoDB有时会增加auto_increment列而不添加值的bug,例如, INSERT ... ON DUPLICATE KEY


小智 5

我有类似的问题.您正在尝试在具有内容且列不可为空的表上应用外键.你有两个选择.

  1. 使要应用外键约束的列可以为空.这样,外键将被应用,因为知道某些字段可以为空.(这就是我所做的.)
  2. 创建要应用外键约束的列,编写查询以将外键插入列中,然后应用外键约束.(没试过,但它应该工作)


小智 5

稍作修复: 在表1中将JoinColumn设置为“ nullable = true”,在表2中将“ UserID”字段设置为“ insertable = false”和“ nullable = true”。

在表1实体中:

@OneToMany(targetEntity=Table2.class, cascade = CascadeType.ALL)
@JoinColumn(name = "UserID", referencedColumnName = "UserID", nullable = true)
private List<Table2> table2List;
Run Code Online (Sandbox Code Playgroud)

在表2实体中:

@Column(insertable = false, nullable = true)
private int UserID;
Run Code Online (Sandbox Code Playgroud)