ข้อผิดพลาด 1452: ไม่สามารถเพิ่มหรืออัปเดตแถวลูกได้: ข้อ จำกัด ของคีย์ภายนอกล้มเหลว


132

ฉันได้สร้างตารางใน MySQL Workbench ดังที่แสดงด้านล่าง:

ตาราง ORDRE:

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;

โต๊ะ PRODUKT:

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;

และโต๊ะ ORDRELINJE:

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_fkFOREIGN KEY ( Ordre) การอ้างอิงOrdre( OrdreID))

ฉันเคยเห็นโพสต์อื่น ๆ ในหัวข้อนี้ แต่โชคไม่ดี ฉันกำลังดูแลบางอย่างหรือมีความคิดว่าจะทำอย่างไร?


คำตอบ:


173

นำมาจากการใช้ข้อ จำกัด สำคัญต่างประเทศ

ความสัมพันธ์ของคีย์นอกเกี่ยวข้องกับตารางพาเรนต์ที่เก็บค่าข้อมูลกลางและตารางลูกที่มีค่าเหมือนกันที่ชี้กลับไปที่พาเรนต์ คำสั่ง FOREIGN KEY ถูกระบุไว้ในตารางลูก

จะปฏิเสธการดำเนินการ INSERT หรือ UPDATE ใด ๆ ที่พยายามสร้างค่าคีย์ต่างประเทศในตารางลูกหากไม่มีค่าคีย์ตัวเลือกที่ตรงกันในตารางหลัก

ดังนั้นError Code: 1452. Cannot add or update a child row: a foreign key constraint failsโดยพื้นฐานแล้วข้อผิดพลาดของคุณหมายความว่าคุณกำลังพยายามเพิ่มแถวในOrdrelinjeตารางของคุณซึ่งไม่มีแถวที่ตรงกัน (OrderID) อยู่ในOrdreตาราง

คุณต้องแทรกแถวลงในOrdreตารางของคุณก่อน


หรือเราสามารถวาง Foreign Key แล้วเพิ่ม Foreign Key หลังการแทรกข้อมูลได้หรือไม่?
Vamsi Pavan Mahesh

@VamsiPavanMahesh ไม่ทำให้แม้ว่าคุณจะทำอย่างนั้น การสร้างคีย์ foriegn ของคุณจะล้มเหลวด้วยข้อผิดพลาดประเภทเดียวกันเนื่องจากจะมีข้อมูลคีย์ไม่ตรงกัน
ราหุล

4
พูดง่ายๆถ้าเด็ก ๆ มีการกำหนดรหัสผู้ปกครองพ่อแม่เหล่านี้จะต้องมีอยู่ และฉันคิดว่าไวยากรณ์ของฉันผิด ... มันช่วยฉันได้มาก ขอบคุณ!
wst

2
แล้วความสัมพันธ์ทางเลือกล่ะ?
Hamed Hamedi

40

คุณได้รับการตรวจสอบข้อ จำกัด นี้เนื่องจากOrdreตารางไม่มีการอ้างอิงที่OrdreIDให้ไว้ในคำสั่งแทรก

ในการแทรกค่าOrdrelinjeคุณต้องป้อนค่าในOrdreตารางก่อนและใช้ค่าเดียวกันOrdreIDในOrderlinjeตาราง

หรือคุณสามารถลบข้อ จำกัด ที่ไม่ใช่ค่าว่างและแทรกค่า NULL ลงไปได้


30

คุณต้องลบข้อมูลในตารางลูกซึ่งไม่มีค่าคีย์ต่างประเทศที่สอดคล้องกับคีย์หลักของตารางหลักหรือลบข้อมูลทั้งหมดจากตารางลูกจากนั้นแทรกข้อมูลใหม่ที่มีค่าคีย์ต่างประเทศเดียวกันกับคีย์หลักในตารางหลัก . ที่ควรจะทำงาน นี่คือวิดีโอ youtube


1
ถูกต้องก่อนที่จะแทรกข้อมูลลงในตาราง Pivot (ที่มีข้อ จำกัด CASCADE) คุณต้องแทรกข้อมูลลงในตารางหลัก เช่นตารางที่ 1 - สิทธิ์; ตารางที่ 2 - บทบาท; ตารางที่ 3 - permission_role; อันดับที่ 1 แทรกลงในตารางสิทธิ์การแทรกครั้งที่ 2 ในตารางบทบาทและสุดท้ายแทรกลงในตาราง permission_role
Deepak Panwar

25

ปัญหาอยู่ที่ข้อ จำกัด สำคัญต่างประเทศ ตามค่าเริ่มต้น (SET FOREIGN_KEY_CHECKS = 1) อ็อพชัน FOREIGN_KEY_CHECKS ระบุว่าจะตรวจสอบข้อ จำกัด คีย์ภายนอกสำหรับตาราง InnoDB หรือไม่ MySQL - ตั้งค่า FOREIGN_KEY_CHECKS

เราสามารถตั้งค่า Foreign Key check เป็นปิดการใช้งานก่อนเรียกใช้ Query ปิดการใช้งานต่างประเทศที่สำคัญ

ดำเนินการหนึ่งในบรรทัดเหล่านี้ก่อนที่จะเรียกใช้แบบสอบถามของคุณจากนั้นคุณสามารถเรียกใช้แบบสอบถามของคุณได้สำเร็จ :)

1) สำหรับเซสชัน (แนะนำ)

SET FOREIGN_KEY_CHECKS=0;

2) ทั่วโลก

SET GLOBAL FOREIGN_KEY_CHECKS=0;

19

โดยทั่วไปข้อผิดพลาดนี้เกิดขึ้นเนื่องจากเรามีค่าบางอย่างในฟิลด์การอ้างอิงของตารางลูกซึ่งไม่มีอยู่ในฟิลด์ที่อ้างอิง / ผู้สมัครของตารางหลัก

บางครั้งเราอาจได้รับข้อผิดพลาดนี้เมื่อเรากำลังจะยื่นข้อ จำกัด ที่สำคัญต่างประเทศตารางที่มีอยู่ (s), มีข้อมูลในพวกเขาแล้ว คำตอบอื่น ๆ บางคำแนะนำให้ลบข้อมูลทั้งหมดจากตารางย่อยจากนั้นใช้ข้อ จำกัด อย่างไรก็ตามนี่ไม่ใช่ตัวเลือกเมื่อเรามีข้อมูลการทำงาน / การผลิตในตารางย่อยแล้ว ในสถานการณ์ส่วนใหญ่เราจะต้องอัปเดตข้อมูลในตารางลูก (แทนที่จะลบออก)

ตอนนี้เราสามารถใช้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ไวยากรณ์


ฉันลบข้อมูลทั้งหมดออกจากตารางแล้วเพิ่มคีย์ต่างประเทศที่เพิ่มเข้าไปแล้วขอบคุณ
Sumit Kumar Gupta

4

ในตารางคีย์ต่างประเทศมีค่าที่ไม่ได้เป็นเจ้าของในตารางคีย์หลักที่เกี่ยวข้องดังนั้นคุณต้องลบข้อมูลทั้งหมดก่อน / ปรับค่าของตารางคีย์ต่างประเทศของคุณตามค่าที่อยู่ในคีย์หลักของคุณ


3

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

สิ่งที่ได้ผลสำหรับฉันคือการพิมพ์รหัส "SET GLOBAL FOREIGN_KEY_CHECKS = 0" หลังจากนั้นฉันก็ปิด MySQL แล้วรีสตาร์ทและฉันก็สามารถอัปโหลดข้อมูลทั้งหมดของฉันได้โดยไม่มีข้อผิดพลาด จากนั้นฉันพิมพ์ "SET GLOBAL FOREIGN_KEY_CHECKS = 1" เพื่อตั้งค่าระบบให้กลับมาเป็นปกติแม้ว่าฉันจะไม่แน่ใจทั้งหมดว่า FOREIGN_KEY_CHECKS ทำอะไร หวังว่านี่จะช่วยได้!


นี่ไม่ใช่แค่สิ่งที่ได้รับการแนะนำแล้วในคำตอบที่โพสต์โดย @ Mr-Faizan? ถ้าไม่โปรดอธิบายว่าคำตอบของคุณเพิ่มอะไร
Adrian Mole

2

สิ่งนี้สามารถแก้ไขได้โดยการแทรกระเบียนที่เกี่ยวข้องในตารางหลักก่อนจากนั้นเราสามารถแทรกระเบียนในคอลัมน์ของตารางย่อยตามลำดับ ตรวจสอบประเภทข้อมูลและขนาดของคอลัมน์ด้วย มันควรจะเหมือนกับคอลัมน์ตารางพาเรนต์แม้แต่เอ็นจิ้นและการเรียงก็ควรเหมือนกัน ลองนี่สิ! นี่คือวิธีที่ฉันแก้ไขของฉัน แก้ไขฉันถ้าฉันผิด


1

ORDRELINJEตารางของคุณเชื่อมโยงกับORDERตารางโดยใช้ข้อ จำกัด ของ Foreign Key constraint 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 ใด ๆ คอมไพเลอร์จะบ่นว่ามีการละเมิดคีย์ต่างประเทศ นี่คือสาเหตุที่คุณได้รับข้อผิดพลาดนี้

Foreign Key คือคีย์หลักของตารางอื่นที่คุณใช้ในตารางใดก็ได้เพื่อเชื่อมโยงระหว่างทั้งสอง คีย์นี้ถูกผูกไว้โดยข้อ จำกัด ของคีย์ต่างประเทศที่คุณระบุขณะสร้างตาราง การดำเนินการใด ๆ กับข้อมูลจะต้องไม่ละเมิดข้อ จำกัด นี้ การละเมิดข้อ จำกัด นี้อาจส่งผลให้เกิดข้อผิดพลาดเช่นนี้

หวังว่าฉันจะทำให้มันชัดเจน


1

ในขณะที่แทรกค่าแอตทริบิวต์คีย์ต่างประเทศขั้นแรกให้ตรวจสอบประเภทแอตทริบิวต์รวมทั้งค่าแอตทริบิวต์คีย์หลักในความสัมพันธ์หลักหากค่าในความสัมพันธ์หลักตรงกันคุณสามารถแทรก / อัปเดตค่าแอตทริบิวต์ลูกได้อย่างง่ายดาย


1

คุณควรเพิ่มข้อมูลจาก REFERENCES KEY ใน PRIMARY TABLE เป็น FOREIGN KEY ใน CHILD TABLE
หมายความว่าอย่าเพิ่มข้อมูลแบบสุ่มไปยังคีย์ต่างประเทศ ، เพียงแค่ใช้ข้อมูลจากคีย์หลักที่สามารถเข้าถึงได้

คำอธิบายข้อมูลในคีย์ต่างประเทศ


1

สิ่งนี้ช่วยฉันได้หลังจากอ่านคำตอบของ @ Mr-Faizan และอื่น ๆ

ยกเลิกการเลือก 'เปิดใช้งานการตรวจสอบคีย์ต่างประเทศ'

ใน phpMyAdmin และกดแบบสอบถาม ฉันไม่รู้เกี่ยวกับ WorkBench แต่คำตอบอื่น ๆ อาจช่วยคุณได้


0

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


0

ไม่ดีบีบสิ่งนี้ที่นี่: กรณีของฉันพยายามสร้างเหมือนสำหรับโพสต์ที่มีอยู่; ในขณะที่ดำเนินการกับฐานข้อมูลเกิดข้อผิดพลาดขึ้น วิธีแก้ปัญหาคือสร้างโพสต์ก่อนแล้วกดไลค์ จากความเข้าใจของฉันถ้า post_id จะถูกบันทึกในตารางไลค์ก่อนอื่นต้องตรวจสอบกับตารางโพสต์เพื่อยืนยันการมีอยู่ ฉันพบว่ามันดีกว่าที่จะมีแบบนี้เพราะมันสมเหตุสมผลกับฉันมากกว่าแบบนั้น ..


0

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

ตัวอย่างเช่นถ้าคุณกำลังเพิ่ม(userid, password)ในtable1จากtable2แล้วจากtable2เพื่อที่ควรจะเหมือนกัน(userid, password)และไม่เหมือน (password,userid)ที่useridเป็นต่างประเทศที่สำคัญในtable2ของtable1


0

ปัญหาเกิดขึ้นเนื่องจากคุณตั้งค่าคีย์ต่างประเทศในตารางลูกหลังจากที่คุณแทรกข้อมูลบางอย่างในตารางลูก

ลองลบข้อมูลทั้งหมดออกจากตารางลูกจากนั้นตั้งค่าคีย์นอกและหลังจากนั้นเพิ่ม / แทรกข้อมูลในตารางก็จะใช้งานได้


0

ตรวจสอบหมายเลข ของบันทึกในตารางหลักที่ตรงกับตารางลูกและคีย์หลักต้องตรงกับการอ้างอิงคีย์ต่างประเทศ สิ่งนี้ใช้ได้กับฉัน


-4

ทำงานได้ 100% ...

ข้อผิดพลาด 1452: ไม่สามารถเพิ่มหรืออัปเดตแถวลูกได้: ข้อ จำกัด ของคีย์ต่างประเทศล้มเหลว .... หากเกิดข้อผิดพลาดประเภทนี้ก่อนอื่นให้ไปที่ตารางนี้และตรวจสอบการตั้งค่า> ถ้า Engine เป็น: InnoDB ให้เปลี่ยนเป็น MyISAM

(และลบการอ้างอิงข้อ จำกัด ต่างประเทศ)

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