Không thể thêm hoặc cập nhật một hàng con: một ràng buộc khóa ngoại không thành công


174

Bảng 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   |     |         |                |
+----------+-------------+------+-----+---------+----------------+

ban 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   |     |         |                |
+------------------+--------------+------+-----+---------+----------------+

Lỗi:

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`)) 

Tôi đã làm gì sai? Tôi đã đọc http://www.w3schools.com/Sql/sql_Forignkey.asp và tôi không thấy có gì sai.


4
Bạn có thể gửi truy vấn gây ra lỗi?
Damp

38
Tóm lại, bạn đang cố gắng chèn / cập nhật một giá trị table2.UserIDkhông tồn tại trong đó table1.UserID.
Joe Stefanelli

Không chắc tại sao nhưng sau khi chuyển cơ sở dữ liệu của tôi từ môi trường windows sang Linux, tôi đã phải xóa và tạo lại một mối quan hệ (đó là khi tôi nhận thấy vấn đề này). Giá trị đã tồn tại, nhưng loại bỏ và thêm lại quan hệ đã cố định nó. Bạn có thể cần phải khá cẩn thận làm như vậy rõ ràng.
johnsnails 7/07/2015

Câu trả lời:


234

Bạn đang gặp phải lỗi này vì bạn đang cố thêm / cập nhật một hàng vào table2đó không có giá trị hợp lệ cho UserIDtrường dựa trên các giá trị hiện được lưu trữ table1. Nếu bạn đăng thêm một số mã tôi có thể giúp bạn chẩn đoán nguyên nhân cụ thể.


PreparedStatement st = Connection.prepareStatement ("Chèn vào bảng2 (UserID, PostID, Tiêu đề, Tóm tắt)" + "giá trị (UserID,?,?,?)");
Tom

15
không chắc chắn những gì downvote là dành cho; Câu trả lời của tôi là hoàn toàn hợp lệ và chính xác.
Brian Driscoll

Hmm ... chắc chắn không phải là một ý tưởng tốt để trộn các tham số được đặt tên với các tham số chưa được đặt tên trong tuyên bố đã chuẩn bị của bạn. nó phải là "giá trị (?,?,?,?)" với giá trị phù hợp cho UserID được chỉ định trong câu lệnh thực thi của bạn.
Brian Driscoll

Vì vậy, tôi cần phải làm gì với một câu lệnh SQL khác để lấy userid từ bảng1?
Tom

5
Rất có thể là 0, thay thế nó bằng Null nếu đó là trường hợp
Jeffrey Nicholson Carré

123

Điều đó có nghĩa là bạn đang cố gắng chèn vào table2một UserIDgiá trị không tồn tại table1.


104

Một cách hack đơn giản có thể là vô hiệu hóa kiểm tra khóa ngoại trước khi thực hiện bất kỳ thao tác nào trên bàn. Truy vấn đơn giản

SET FOREIGN_KEY_CHECKS=0

Điều này sẽ vô hiệu hóa khớp khóa ngoại với bất kỳ bảng nào khác. Sau khi bạn hoàn thành với bảng, kích hoạt lại

SET FOREIGN_KEY_CHECKS=1

Điều này làm việc cho tôi rất nhiều lần.


Làm thế nào tôi sử dụng này ??
Sachin từ Pune

2
@SachinfromPune chỉ cần thêm SET FOREIGN_KEY_CHECKS = 0; khi bắt đầu tập tin mysql và SET FOREIGN_KEY_CHECKS = 1; ở cuối tệp mysql, nhập lại dữ liệu
inrsaurabh

1
Đây không phải là vấn đề? Bạn mất tính toàn vẹn tham chiếu, phải không?
roadrunner66

Tính toàn vẹn tham chiếu được hỗ trợ bởi sự hiện diện của các mục chỉ mục chính xác. Miễn là bạn đã có đúng khóa và chỉ mục của mình, bạn sẽ có thể vô hiệu hóa kiểm tra khóa trong quá trình nhập hàng loạt.
Vernon Keenan

46

Tôi đã phát hiện ra một trường hợp kỳ lạ khác: Nếu bạn vô tình tạo khóa ngoại từ bảng InnoDB sang bảng MyISAM, MySQL sẽ ném lỗi này tại thời điểm chèn ngay cả khi dữ liệu có giá trị.

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


1
Vâng, tôi có cùng một vấn đề. Hai bảng nên là InnoDB!
emeraldhieu

2
Tôi đã có cùng một vấn đề, cảm ơn vì tiền boa. Đây là một liên kết đến tài liệu MySQL về cách chuyển đổi các bảng từ MyISAM sang InnoDB dev.mysql.com/doc/refman/5.7/en/ nhiệt TLDR: ALTER TABLE table_name Engine = InnoDB;
Guilherme Vaz

Thật vậy, đây là trường hợp trong cơ sở dữ liệu của tôi. Tôi quyết định thay đổi công cụ MyISAM thành InnoDB. Cuối cùng, tôi có thể làm việc với cơ sở dữ liệu theo cách tôi muốn.
Mike

17

Bạn đang gặp phải lỗi này vì có một số giá trị int table2.UserIDkhông tồn tại table1.UserID(Tôi đoán rằng bạn đã giải quyết thủ công table2.UserIDgiá trị trước khi bạn tạo khóa ngoại này).
Một ví dụ cho cảnh này: table1.UserIDnhận các giá trị 1,2,3 và table2.UserIDnhận các giá trị 4 (thêm bằng tay). Vì vậy, khi bạn thực hiện một chính nước ngoài, họ không thể tìm thấy UserID = 4từ table1và lỗi sẽ ocurse.
Để khắc phục lỗi này, chỉ cần xóa UserID = 4khỏi table2hoặc bạn có thể làm trống cả hai và sau đó tạo khóa ngoại và.
Chúc may mắn!


11

Điều này làm tôi mất một lúc để tìm ra. Nói một cách đơn giản, bảng tham chiếu bảng khác đã có dữ liệu trong đó và một hoặc nhiều giá trị của nó không tồn tại trong bảng cha.

ví dụ Table2 có các dữ liệu sau:

UserID    PostID    Title    Summary
5         1         Lorem    Ipsum dolor sit

Bảng 1

UserID    Password    Username    Email
9         ********    JohnDoe     john@example.com

Nếu bạn cố gắng THAY ĐỔI bảng2 và thêm khóa ngoại thì truy vấn sẽ thất bại vì UserID = 5 không tồn tại trong Bảng1.


10

Nếu bạn đã chèn một hàng vào bảng 1 trước khi tạo khóa ngoại trong bảng 2, thì bạn sẽ gặp lỗi ràng buộc khóa ngoại, bởi vì giá trị tăng tự động là 2 trong bảng 1 và 1 trong bảng 2. Để giải quyết điều này, bạn phải cắt bớt bảng 1 và đặt giá trị tăng tự động trở lại 1. Sau đó, bạn có thể thêm bảng 2.


10

Đảm bảo rằng bạn đã đặt công cụ cơ sở dữ liệu thành InnoDB vì trong khóa ngoại và giao dịch MyISAM không được hỗ trợ


2
THAY ĐỔI BẢNG my_table ĐỘNG CƠ = InnoDB;
Bishwas Mishra

7

Chỉ cần sửa một chút: Làm cho JoinColumn 'nullable = true' trong Bảng1 và 'UserID' 'insertable = false' và 'nullable = true' trong Bảng2.

Trong Thực thể Bảng1:

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

Trong thực thể Bảng2:

@Column(insertable = false, nullable = true)
private int UserID;

Câu trả lời này hoàn toàn giải quyết vấn đề của tôi, cảm ơn bạn rất nhiều vì đã chia sẻ điều này. Khóa cho tôi là thêm @Column (insertable = false, nullable = true) trên tệp mà tôi đang sử dụng làm khóa tìm kiếm trong đối tượng / bảng con của tôi.
Israel

6

Tôi chỉ có cùng một vấn đề giải pháp là dễ dàng.

Bạn đang cố gắng thêm id vào bảng con không tồn tại trong bảng cha.

kiểm tra tốt, vì InnoDB có lỗi đôi khi làm tăng cột auto_increment mà không thêm giá trị, ví dụ: INSERT ... ON DUPLICATE KEY


nghiêm túc? không chèn tham chiếu id không tồn tại ... chỉ cần kiểm tra
Blaztix

5

Tôi đã có một vấn đề tương tự. Bạn đang cố gắng áp dụng khóa ngoại trên bảng có nội dung và cột không thể rỗng. Bạn có hai lựa chọn.

  1. Đặt cột bạn muốn áp dụng các ràng buộc khóa ngoài thành không thể thực hiện được. Bằng cách đó, khóa ngoại sẽ áp dụng khi biết rằng một số trường có thể là null. ( Đây là những gì tôi đã làm. )
  2. Tạo cột bạn muốn áp dụng ràng buộc khóa ngoài, viết truy vấn để chèn khóa ngoại vào cột và sau đó áp dụng các ràng buộc khóa ngoài. ( Không thử cái này nhưng nó sẽ hoạt động )

4

Đảm bảo giá trị mà bạn đang chèn vào khóa ngoại tồn tại trong bảng cha. Điều đó đã giúp tôi. Ví dụ: nếu bạn chèn user_id = 2vào table.2, nhưng table.1không có a user_id = 2, thì ràng buộc sẽ đưa ra lỗi. Của tôi là mã lỗi # 1452 chính xác. Hy vọng điều này sẽ giúp bất cứ ai khác có cùng một vấn đề!


3

Tôi có cùng một vấn đề, và lý do là tôi đã có một hàng trong bảng đầu tiên trước khi thêm khóa ngoại.


1

Tôi cũng gặp phải vấn đề tương tự và vấn đề là giá trị mục nhập bảng cha mẹ của tôi không khớp với giá trị bảng khóa ngoại. Vì vậy, hãy thử sau khi xóa tất cả các hàng ..


Ràng buộc yêu cầu người dùng được tham chiếu trong Bảng 2 đã được xác định trong Bảng 1.
sorak

1

Trong trường hợp nếu các giải pháp được cung cấp bởi người khác đã không làm việc. Sau đó, bạn nên thử kiểm tra Công cụ cơ sở dữ liệu của Bảng cha mẹ và trẻ em. Trong trường hợp của tôi, tôi đã đặt công cụ của bảng cha mẹ thành "MyISAM", thay đổi nó thành InnoDB đã sửa nó.

Hy vọng điều này sẽ giúp những người khác bị mắc kẹt như tôi.


1

Bạn không nên đặt trường ondelete vào một tầng trong cơ sở dữ liệu.

Vì vậy, đặt trường onDelete thành RESTRICT

Chúc may mắn ♥


0

Một trường hợp kỳ lạ khác đã cho tôi lỗi này. Tôi đã nhầm lẫn các khóa ngoại của tôi với khóa chính id. Điều này được gây ra bởi các lệnh bảng thay đổi không chính xác. Tôi đã tìm thấy điều này bằng cách truy vấn bảng Information_SCHema (Xem câu trả lời stackoverflow này)

Bảng đã bị nhầm lẫn đến mức không thể sửa được bằng bất kỳ lệnh ALTER TABLE nào . Cuối cùng tôi đã bỏ cái bàn xuống và dựng lại nó. Điều này đã thoát khỏi tính toàn vẹnError.


0

Có thể trong khi bạn đã thêm userIDcột, có một dữ liệu cho bảng nhất định mà nó được thiết lập để nó sẽ có giá trị mặc định 0, hãy thử thêm cột mà không cóNOT NULL


0

Tôi cũng gặp lỗi này: "Không thể thêm hoặc cập nhật hàng con: ràng buộc khóa ngoại không thành công". Tôi đã gặp lỗi khi thêm một hàng mới vào bảng cha

Vấn đề là ràng buộc khóa ngoại đã được xác định trên bảng cha thay vì bảng con.


0

Nếu bạn sử dụng chỉ mục mysql hoặc mối quan hệ giữa các bảng, trước tiên, bạn xóa các colums (ví dụ: city_id) và tạo các colums mới có cùng tên (ví dụ: city_id). Sau đó thử lại ...


0

Có bất kỳ dữ liệu hiện có mà bảng chứa? Nếu vậy, hãy thử xóa tất cả dữ liệu trong bảng bạn muốn thêm khóa ngoại. Sau đó chạy mã (thêm khóa ngoại) một lần nữa.

Tôi đã gặp vấn đề này rất nhiều lần. Việc xóa tất cả dữ liệu trong bảng sẽ hoạt động khi bạn muốn thêm khóa ngoại vào bảng hiện có.

Hy vọng điều này hoạt động :)


0

Xóa các chỉ mục của trường UserID của bảng2. Nó phù hợp với tôi


-1

bảng con hạn chế khóa ngoại

Vấn đề này có thể tăng do lý do sau:

Nếu bạn đang làm điều đó trong Spring mvc, bạn cần mô tả rõ ràng loại id, bởi vì đôi khi mysql không thể nhận ra loại id. vì vậy bạn đặt rõ ràng như trong cả hai bảng trong lớp thực thể của bạn@GeneratedValue (strategy = GenerationType.IDENTITY)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.