ไม่สามารถเพิ่มหรืออัปเดตแถวลูกได้: ข้อ จำกัด รหัสต่างประเทศล้มเหลว


174

ตารางที่ 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   |     |         |                |
+----------+-------------+------+-----+---------+----------------+

table2

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

ข้อผิดพลาด:

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

ฉันทำอะไรผิด ฉันอ่านhttp://www.w3schools.com/Sql/sql_foreignkey.aspและฉันไม่เห็นว่ามีอะไรผิดปกติ


4
คุณสามารถโพสต์คำถามที่ทำให้เกิดข้อผิดพลาดได้หรือไม่
ชื้น

38
ในการสรุปคุณกำลังพยายามที่จะแทรก / ปรับปรุงค่าในที่ไม่ได้อยู่ในtable2.UserID table1.UserID
Joe Stefanelli

ไม่แน่ใจว่าทำไม แต่หลังจากย้ายฐานข้อมูลของฉันจากสภาพแวดล้อม windows ไปยัง Linux ฉันต้องลบและสร้างความสัมพันธ์ใหม่ (นั่นคือเมื่อฉันสังเกตเห็นปัญหา) ค่านั้นมีอยู่ แต่การลบและเพิ่มความสัมพันธ์นั้นแก้ไขอีกครั้ง คุณอาจต้องระวังให้ดี
johnsnails

คำตอบ:


235

คุณได้รับข้อผิดพลาดนี้เนื่องจากคุณพยายามเพิ่ม / อัปเดตแถวtable2ที่ไม่มีค่าที่ถูกต้องสำหรับUserIDฟิลด์ตามค่าที่เก็บไว้ในtable1ปัจจุบัน หากคุณโพสต์รหัสเพิ่มเติมฉันสามารถช่วยคุณวิเคราะห์สาเหตุที่เฉพาะเจาะจงได้


PreparedStatement st = connection.prepareStatement ("แทรกลงในตารางที่ 2 (ID ผู้ใช้ PostID ชื่อเรื่องสรุป)" + "ค่า (UserID,?,?,?)");
Tom

15
ไม่แน่ใจว่า downvote นั้นมีไว้เพื่ออะไร คำตอบของฉันถูกต้องสมบูรณ์และถูกต้อง
ไบรอันคอลล์

อืม ... ไม่ใช่ความคิดที่ดีที่จะผสมพารามิเตอร์ที่มีชื่อกับพารามิเตอร์ที่ไม่มีชื่อในคำสั่งที่เตรียมไว้ของคุณ ควรเป็น "values ​​(?,?,?,?)" ด้วยค่าที่เหมาะสมสำหรับ UserID ที่ระบุในคำสั่ง execute ของคุณ
ไบรอันคอลล์

ดังนั้นฉันต้องทำกับคำสั่ง SQL อื่นเพื่อรับหมายเลขผู้ใช้จาก table1?
Tom

5
น่าจะเป็น 0 แทนที่มันด้วย Null หากเป็นกรณีนี้
Jeffrey Nicholson Carré


104

แฮ็คง่ายๆสามารถปิดใช้งานการตรวจสอบ foreign key ก่อนที่จะดำเนินการใด ๆ บนโต๊ะ เพียงแค่สอบถาม

SET FOREIGN_KEY_CHECKS=0

วิธีนี้จะปิดใช้งานการจับคู่คีย์ต่างประเทศกับตารางอื่น ๆ หลังจากที่คุณทำตารางเสร็จแล้วให้เปิดใช้งานอีกครั้ง

SET FOREIGN_KEY_CHECKS=1

มันใช้งานได้สำหรับฉันหลายครั้ง


ฉันจะใช้สิ่งนี้ได้อย่างไร?
Sachin จาก Pune

2
@SchinfromPune เพียงเพิ่ม SET FOREIGN_KEY_CHECKS = 0; เมื่อเริ่มต้นไฟล์ mysql และ SET FOREIGN_KEY_CHECKS = 1; ในตอนท้ายของไฟล์ mysql ให้นำเข้าข้อมูลอีกครั้ง
inrsaurabh

1
นี่ไม่ใช่ปัญหาหรือเปล่า คุณสูญเสียความสมบูรณ์ของการอ้างอิงใช่มั้ย
roadrunner66

Referential Integrity ได้รับการสนับสนุนโดยการมีรายการดัชนีที่ถูกต้อง ตราบใดที่คุณมีกุญแจและดัชนีของคุณถูกต้องคุณควรจะสามารถปิดใช้งานการตรวจสอบคีย์ในระหว่างการป้อนข้อมูลจำนวนมากได้
เวอร์นอนคีแน

46

ฉันค้นพบกรณีแปลกใหม่: ถ้าคุณบังเอิญสร้างคีย์ต่างประเทศจากตาราง InnoDB ไปยังตาราง MyISAM, MySQL จะพ่นข้อผิดพลาดนี้เมื่อทำการแทรกแม้ว่าข้อมูลจะไม่ถูกต้องก็ตาม

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


1
ใช่ฉันมีปัญหาเดียวกัน สองตารางควรเป็น InnoDB!
emeraldhieu

2
ฉันมีปัญหาเดียวกันขอบคุณสำหรับเคล็ดลับ นี่คือลิงค์ไปยังเอกสารประกอบ MySQL เกี่ยวกับวิธีการแปลงตารางจาก MyISAM เป็น InnoDB dev.mysql.com/doc/refman/5.7/en/… TLDR: ALTER Table table_name ENGINE = InnoDB;
Guilherme Vaz

อันที่จริงนี่เป็นกรณีในฐานข้อมูลของฉัน ฉันตัดสินใจเปลี่ยนเครื่องยนต์ MyISAM เป็น InnoDB ในที่สุดฉันสามารถทำงานกับฐานข้อมูลในแบบที่ฉันต้องการ
Mike

17

คุณได้รับข้อผิดพลาดนี้เนื่องจากมีบางค่า int table2.UserIDที่ไม่ได้อยู่ในtable1.UserID(ฉันเดาว่าคุณได้กำหนดtable2.UserIDมูลค่า manualy ก่อนที่คุณจะสร้างคีย์ต่างประเทศนี้)
ตัวอย่างหนึ่งสำหรับฉากนี้: table1.UserIDรับค่า 1,2,3 และtable2.UserIDรับค่า 4 (เพิ่มด้วยตนเอง) ดังนั้นเมื่อคุณทำให้ต่างประเทศที่สำคัญพวกเขาไม่สามารถหาUserID = 4จากtable1และข้อผิดพลาดจะ ocurse
เพื่อแก้ไขข้อผิดพลาดนี้เพียง แต่เอาUserID = 4มาจากtable2หรือคุณสามารถว่างเปล่าทั้งสองของพวกเขาแล้วสร้างคีย์ต่างประเทศและ
โชคดี!


11

นี่ใช้เวลาสักครู่กว่าจะคิดออก พูดง่ายๆคือตารางที่อ้างอิงถึงตารางอื่นมีข้อมูลอยู่แล้วและไม่มีค่าอยู่ในตารางหลัก

เช่น Table2 มีข้อมูลต่อไปนี้:

UserID    PostID    Title    Summary
5         1         Lorem    Ipsum dolor sit

ตารางที่ 1

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

หากคุณพยายามที่จะแก้ไข table2 และเพิ่มคีย์ต่างประเทศการสืบค้นจะล้มเหลวเนื่องจากไม่มี ID ผู้ใช้ = 5 ใน Table1


10

หากคุณแทรกแถวในตาราง 1 ก่อนสร้าง foreign key ในตาราง 2 คุณจะได้รับข้อผิดพลาดข้อ จำกัด foreign key เนื่องจากค่าการเพิ่มอัตโนมัติคือ 2 ในตาราง 1 และ 1 ในตาราง 2 เพื่อแก้ปัญหานี้คุณต้อง ตัดทอนตารางที่ 1 และตั้งค่าการเพิ่มอัตโนมัติกลับเป็น 1 จากนั้นคุณสามารถเพิ่มตารางที่ 2


10

ตรวจสอบให้แน่ใจว่าคุณได้ตั้งค่าเอ็นจิ้นฐานข้อมูลเป็น InnoDB เพราะใน MyISAM foreign key และธุรกรรมไม่ได้รับการสนับสนุน


2
ALTER TABLE my_table ENGINE = InnoDB;
Bishwas Mishra

7

แก้ไขนิดหน่อย: ทำให้ JoinColumn 'nullable = true' ใน Table1 และ 'UserID' field 'insertable = false' และ 'nullable = true' ใน Table2

ใน Table1 Entity:

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

ใน Table2 Entity:

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

คำตอบนี้แก้ปัญหาทั้งหมดของฉันขอบคุณมากสำหรับการแบ่งปัน กุญแจสำคัญสำหรับฉันเพิ่ม @Column (insertable = false, nullable = true) ในไฟล์ที่ฉันใช้เป็นคีย์ foraeing ในวัตถุ / ตารางลูกของฉัน
อิสราเอล

6

ฉันเพิ่งมีปัญหาเดียวกันทางออกง่ายมาก

คุณกำลังพยายามเพิ่มรหัสในตารางลูกที่ไม่มีอยู่ในตารางหลัก

ตรวจสอบอย่างดีเนื่องจาก InnoDB มีข้อผิดพลาดที่บางครั้งเพิ่มคอลัมน์ auto_increment โดยไม่ต้องเพิ่มค่าเช่น INSERT ... ON DUPLICATE KEY


อย่างจริงจัง? อย่าใส่รหัสอ้างอิงที่ไม่มีอยู่ ... แค่ตรวจสอบ
Blaztix

5

ฉันมีปัญหาที่คล้ายกัน คุณพยายามที่จะใช้รหัสที่ต่างประเทศในตารางที่มีเนื้อหาและคอลัมน์นั้นไม่สามารถใช้ได้ คุณมีสองตัวเลือก

  1. ทำให้คอลัมน์ที่คุณต้องการใช้ข้อ จำกัด กุญแจต่างประเทศเป็นโมฆะ วิธีนี้จะทำให้การใช้คีย์ต่างประเทศรู้ว่าบางฟิลด์สามารถเป็นโมฆะได้ ( นี่คือสิ่งที่ฉันทำ )
  2. สร้างคอลัมน์ที่คุณต้องการใช้ข้อ จำกัด foreign key เขียนแบบสอบถามเพื่อแทรก foreign key ลงในคอลัมน์จากนั้นใช้ข้อ จำกัด foreign key ( ไม่ได้ลองสิ่งนี้ แต่ควรใช้งานได้ )

4

ตรวจสอบให้แน่ใจว่าค่าที่คุณใส่เข้าไปใน foreign key นั้นมีอยู่ในตาราง parent นั่นช่วยฉัน ตัวอย่างเช่นถ้าคุณแทรกuser_id = 2เข้าไปtable.2แต่table.1ไม่มี a user_id = 2ข้อ จำกัด ก็จะทำให้เกิดข้อผิดพลาด ฉันเป็นรหัสข้อผิดพลาด # 1452 ที่จะต้องแน่นอน หวังว่านี่จะช่วยให้คนอื่นที่มีปัญหาเดียวกัน!


3

ฉันมีปัญหาเดียวกันและสาเหตุที่ฉันมีแถวในตารางแรกก่อนที่จะเพิ่มคีย์ต่างประเทศ


1

ฉันยังประสบปัญหาเดียวกันและปัญหาคือค่ารายการตารางหลักของฉันไม่ตรงกับค่าตารางคีย์ต่างประเทศ ดังนั้นโปรดลองล้างแถวทั้งหมดด้วย


ข้อ จำกัด ต้องการให้ผู้ใช้ที่อ้างอิงใน Table2 ถูกกำหนดไว้แล้วใน Table1
sorak

1

ในกรณีที่โซลูชันที่ผู้อื่นให้บริการไม่ได้ผล จากนั้นคุณควรลองตรวจสอบเอ็นจิ้นฐานข้อมูลของพาเรนต์และตารางลูกในกรณีของฉันฉันตั้งเอ็นจิ้นของตารางหลักเป็น "MyISAM" เปลี่ยนเป็น InnoDB แก้ไข

หวังว่านี่จะช่วยให้คนอื่นที่ติดอยู่กับฉัน


1

คุณไม่ควรใส่ฟิลด์ ondelete กับ cascade ในฐานข้อมูล

ดังนั้นตั้งค่าฟิลด์ onDelete เป็น RESTRICT

ขอให้โชคดี


0

อีกกรณีแปลกที่ให้ฉันข้อผิดพลาดนี้ ฉันอ้างอิงคีย์ต่างประเทศของฉันผิดไปยังคีย์หลัก id สิ่งนี้เกิดจากคำสั่งเปลี่ยนแปลงตารางที่ไม่ถูกต้อง ฉันพบสิ่งนี้โดยการสอบถามตาราง INFORMATION_SCHEMA (ดูคำตอบสแต็คโอเวอร์โฟลว์นี้)

ตารางสับสนมากจนไม่สามารถแก้ไขได้โดยคำสั่งALTER TABLE ในที่สุดฉันก็ทิ้งโต๊ะและสร้างมันขึ้นมาใหม่ นี่เป็นการกำจัด integrityError


0

บางทีในขณะที่คุณเพิ่มuserIDคอลัมน์มีข้อมูลสำหรับตารางบางตารางที่สร้างขึ้นเพื่อให้มีค่าเริ่มต้น0ลองเพิ่มคอลัมน์โดยไม่ต้องNOT NULL


0

ฉันยังได้รับข้อผิดพลาดนี้: "ไม่สามารถเพิ่มหรืออัปเดตแถวลูกได้: ข้อ จำกัด รหัสต่างประเทศล้มเหลว" ฉันพบข้อผิดพลาดเมื่อเพิ่มแถวใหม่ลงในตารางหลัก

ปัญหาคือว่ามีการกำหนดข้อ จำกัด foreign key ไว้ในตารางหลักแทนที่จะเป็นตารางลูก


0

ถ้าคุณใช้ดัชนี mysql หรือความสัมพันธ์ระหว่างตารางอันดับแรกให้คุณลบ colums (ตัวอย่างเช่น: city_id) และสร้าง colums ใหม่ที่มีชื่อเดียวกัน (เช่น: city_id) จากนั้นลองอีกครั้ง ...


0

มีข้อมูลใดที่มีอยู่ในตารางหรือไม่ หากเป็นเช่นนั้นให้ลองล้างข้อมูลทั้งหมดในตารางที่คุณต้องการเพิ่มรหัสต่างประเทศ จากนั้นเรียกใช้รหัส (เพิ่มรหัสต่างประเทศ) อีกครั้ง

ฉันพบปัญหานี้หลายครั้ง การล้างข้อมูลทั้งหมดในตารางนี้จะทำงานเมื่อคุณต้องการเพิ่ม foreign key ในตารางที่มีอยู่

หวังว่างานนี้ :)



0

ข้อผิดพลาดนั้นเกิดขึ้นเมื่อคุณต้องการเพิ่มคีย์ต่างประเทศที่มีค่าที่ไม่มีอยู่ในคีย์หลักของตารางหลัก คุณต้องแน่ใจว่าคีย์ผู้ใช้ใหม่ foreign ID ใน table2 มีค่าที่มีอยู่ในคีย์หลักของ table1 บางครั้งโดยค่าเริ่มต้นมันเป็นโมฆะหรือเท่ากับ 0

คุณสามารถอัพเดตฟิลด์ทั้งหมดของ foreign key ใน table2 ด้วยค่าที่มีอยู่ในคีย์หลักของ table1

update table2 set UserID = 1 where UserID is null

หากคุณต้องการเพิ่มรหัสผู้ใช้ที่แตกต่างกันคุณต้องแก้ไขแต่ละแถวด้วยค่าที่คุณต้องการ


-1

ข้อ จำกัด คีย์ต่างประเทศของตารางลูกไม่สำเร็จ

ปัญหานี้อาจเพิ่มขึ้นเนื่องจากเหตุผลดังต่อไปนี้:

หากคุณกำลังทำอยู่ใน Spring mvc คุณจะต้องอธิบายประเภท id อย่างชัดเจนเพราะบางครั้ง mysql ไม่สามารถจำแนกประเภทของ id ได้ ดังนั้นคุณจึงตั้งค่าอย่างชัดเจนในตารางทั้งสองในคลาสเอนทิตีของคุณ@GeneratedValue (strategy = GenerationType.IDENTITY)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.