Eine untergeordnete Zeile kann nicht hinzugefügt oder aktualisiert werden: Eine Fremdschlüsseleinschränkung schlägt fehl

174

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

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

Error:

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

Was habe ich falsch gemacht? Ich habe http://www.w3schools.com/Sql/sql_foreignkey.asp gelesen und sehe nicht, was los ist.

Tom
quelle
4
Können Sie die Abfrage posten, die den Fehler auslöst?
Feucht
38
Kurz gesagt, Sie versuchen, einen Wert einzufügen / zu aktualisieren, der in table2.UserIDnicht vorhanden ist table1.UserID.
Joe Stefanelli
Ich weiß nicht warum, aber nachdem ich meine Datenbank von einer Windows-Umgebung auf Linux verschoben hatte, musste ich eine Beziehung löschen und neu erstellen (da bemerkte ich das Problem). Der Wert war vorhanden, wurde jedoch durch Entfernen und erneutes Hinzufügen der Beziehung behoben. Möglicherweise müssen Sie dabei ziemlich vorsichtig sein.
Johnsnails

Antworten:

234

Sie erhalten diesen Fehler, weil Sie versuchen, eine Zeile hinzuzufügen / zu aktualisieren table2, die keinen gültigen Wert für das UserIDFeld hat, basierend auf den aktuell gespeicherten Werten table1. Wenn Sie weiteren Code veröffentlichen, kann ich Ihnen bei der Diagnose der spezifischen Ursache helfen.

Brian Driscoll
quelle
PreparedStatement st = connection.prepareStatement ("In Tabelle 2 einfügen (Benutzer-ID, Post-ID, Titel, Zusammenfassung)" + "Werte (Benutzer-ID,?,?,?)");
Tom
15
nicht sicher, wofür die Ablehnung ist; Meine Antwort ist vollkommen gültig und richtig.
Brian Driscoll
Hmm ... es ist definitiv keine gute Idee, benannte Parameter mit unbenannten Parametern in Ihrer vorbereiteten Anweisung zu mischen. Es sollte "Werte (?,?,?,?)" sein, wobei der entsprechende Wert für die Benutzer-ID in Ihrer execute-Anweisung angegeben ist.
Brian Driscoll
Muss ich also eine andere SQL-Anweisung ausführen, um die Benutzer-ID aus Tabelle1 abzurufen?
Tom
5
Höchstwahrscheinlich eine 0, ersetzen Sie sie durch Null, wenn dies der Fall ist
Jeffrey Nicholson Carré
123

Dies bedeutet, dass Sie versuchen, in table2einen UserIDWert einzufügen, der in nicht vorhanden ist table1.

Rami C.
quelle
104

Ein einfacher Hack kann darin bestehen, Fremdschlüsselprüfungen zu deaktivieren, bevor eine Operation für die Tabelle ausgeführt wird. Einfach abfragen

SET FOREIGN_KEY_CHECKS=0

Dadurch wird die Fremdschlüsselübereinstimmung mit anderen Tabellen deaktiviert. Nachdem Sie mit der Tabelle fertig sind, aktivieren Sie sie erneut

SET FOREIGN_KEY_CHECKS=1

Das funktioniert bei mir oft.

Sandeep Giri
quelle
Wie benutze ich das?
Sachin aus Pune
2
@SachinfromPune füge einfach SET FOREIGN_KEY_CHECKS = 0 hinzu; beim Start der MySQL-Datei und SET FOREIGN_KEY_CHECKS = 1; am Ende der MySQL-Datei Daten erneut
importieren
1
Ist das nicht problematisch? Sie verlieren die referenzielle Integrität, richtig?
Roadrunner66
Die referenzielle Integrität wird durch das Vorhandensein der richtigen Indexeinträge unterstützt. Solange Sie Ihre Schlüssel und Indizes richtig eingestellt haben, sollten Sie in der Lage sein, die Schlüsselprüfung während einer Masseneingabe zu deaktivieren.
Vernon Keenan
46

Ich habe einen weiteren seltsamen Fall entdeckt: Wenn Sie versehentlich einen Fremdschlüssel aus einer InnoDB-Tabelle in eine MyISAM-Tabelle erstellen, gibt MySQL diesen Fehler zum Zeitpunkt des Einfügens aus, auch wenn die Daten ansonsten gültig sind.

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

NickZoic
quelle
1
Ja, ich habe das gleiche Problem. Zwei Tische sollten InnoDB sein!
Smaragdhieu
2
Ich hatte das gleiche Problem, danke für den Tipp. Hier ist ein Link zur MySQL-Dokumentation zum Konvertieren von Tabellen von MyISAM nach InnoDB dev.mysql.com/doc/refman/5.7/en/… TLDR: ALTER TABLE table_name ENGINE = InnoDB;
Guilherme Vaz
Dies war in meiner Datenbank tatsächlich der Fall. Ich habe beschlossen, die MyISAM-Engine auf InnoDB umzustellen. Endlich kann ich mit der Datenbank so arbeiten, wie ich es wollte.
Mike
17

Sie erhalten diesen Fehler, weil es einen Wert int table2.UserIDgibt, der nicht vorhanden ist table1.UserID(ich denke, Sie haben den table2.UserIDWert manuell festgelegt, bevor Sie diesen Fremdschlüssel erstellt haben).
Ein Beispiel für diese Szene: table1.UserIDWerte 1,2,3 und table2.UserIDWerte 4 abrufen (manuell hinzufügen). Also , wenn Sie einen Fremdschlüssel zu machen, können sie nicht finden UserID = 4aus table1und der Fehler wird ocurse.
Um diesen Fehler zu beheben, entfernen Sie einfach UserID = 4aus , table2oder Sie können beide leer und dann erstellen Sie den Fremdschlüssel und.
Viel Glück!

Justin
quelle
11

Ich brauchte eine Weile, um das herauszufinden. Einfach ausgedrückt, die Tabelle, die auf die andere Tabelle verweist, enthält bereits Daten, und einer oder mehrere ihrer Werte sind in der übergeordneten Tabelle nicht vorhanden.

Beispiel: Tabelle 2 enthält die folgenden Daten:

UserID    PostID    Title    Summary
5         1         Lorem    Ipsum dolor sit

Tabelle 1

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

Wenn Sie versuchen, Tabelle2 zu ändern und einen Fremdschlüssel hinzuzufügen, schlägt die Abfrage fehl, da Benutzer-ID = 5 in Tabelle1 nicht vorhanden ist.

Sbudah
quelle
10

Wenn Sie vor dem Erstellen des Fremdschlüssels in Tabelle 2 eine Zeile in Tabelle 1 eingefügt haben, wird ein Fremdschlüsseleinschränkungsfehler angezeigt, da der Wert für die automatische Inkrementierung in Tabelle 1 2 und in Tabelle 2 1 beträgt. Um dies zu lösen, müssen Sie Schneiden Sie Tabelle 1 ab und setzen Sie den Wert für die automatische Inkrementierung wieder auf 1. Anschließend können Sie Tabelle 2 hinzufügen.

Attaque
quelle
10

Stellen Sie sicher, dass Sie das Datenbankmodul auf InnoDB eingestellt haben, da in MyISAM Fremdschlüssel und Transaktion nicht unterstützt werden

Aman Maurya
quelle
2
ALTER TABLE my_table ENGINE = InnoDB;
Bishwas Mishra
7

Nur eine kleine Korrektur: Machen Sie die JoinColumn 'nullable = true' in Tabelle1 und das 'UserID'-Feld' insertable = false 'und' nullable = true 'in Tabelle2.

In Tabelle 1 Entität:

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

In Tabelle 2 Entität:

@Column(insertable = false, nullable = true)
private int UserID;
Ujjwal Chaudhary
quelle
Diese Antwort hat mein Problem völlig gelöst. Vielen Dank, dass Sie dies geteilt haben. Der Schlüssel für mich war das Hinzufügen der @ Spalte (insertable = false, nullable = true) zu der Datei, die ich als Foraeing-Schlüssel in meinem untergeordneten Objekt / meiner untergeordneten Tabelle verwende.
Israelm
6

Ich hatte gerade das gleiche Problem, die Lösung ist einfach.

Sie versuchen, der untergeordneten Tabelle eine ID hinzuzufügen, die in der übergeordneten Tabelle nicht vorhanden ist .

Überprüfen Sie dies gut, da InnoDB den Fehler aufweist, der manchmal die Spalte auto_increment vergrößert, ohne beispielsweise Werte hinzuzufügen. INSERT ... ON DUPLICATE KEY

Blaztix
quelle
Ernsthaft?
Fügen
5

Ich hatte ein ähnliches Problem. Sie versuchen, einen Fremdschlüssel auf eine Tabelle anzuwenden, deren Inhalt und die Spalte nicht nullwertfähig sind. Sie haben zwei Möglichkeiten.

  1. Stellen Sie die Spalte, auf die Sie Fremdschlüsseleinschränkungen anwenden möchten, auf null. Auf diese Weise wird der Fremdschlüssel angewendet, da einige Felder nullwertfähig sein können. ( Das habe ich getan. )
  2. Erstellen Sie die Spalte, auf die Sie die Fremdschlüsseleinschränkung anwenden möchten, schreiben Sie eine Abfrage, um den Fremdschlüssel in die Spalte einzufügen, und wenden Sie dann die Fremdschlüsseleinschränkungen an. ( Habe das nicht ausprobiert, aber es sollte funktionieren )
Jacob
quelle
4

Stellen Sie sicher, dass der Wert, den Sie in den Fremdschlüssel einfügen, in der übergeordneten Tabelle vorhanden ist. Das hat mir geholfen. Wenn Sie zum Beispiel einfügen user_id = 2in table.2, aber table.1nicht eine hat user_id = 2, dann wird der Zwang einen Fehler aus. Meins war Fehlercode # 1452 um genau zu sein. Hoffe das hilft allen anderen mit dem gleichen Problem!

Dustin Hammack
quelle
3

Ich hatte das gleiche Problem und der Grund war, dass ich vor dem Hinzufügen des Fremdschlüssels eine Zeile in der ersten Tabelle hatte.

Ouissal
quelle
1

Ich hatte auch das gleiche Problem und das Problem war, dass der Wert meiner übergeordneten Tabelleneinträge nicht mit dem Wert der Fremdschlüsseltabelle übereinstimmt. Also bitte versuchen Sie nach dem Löschen alle Zeilen ..

Justin Jose
quelle
Die Einschränkung erfordert, dass Benutzer, auf die in Tabelle 2 verwiesen wird, bereits in Tabelle 1 definiert sind.
Sorak
1

Für den Fall, dass die von anderen bereitgestellten Lösungen nicht funktionierten. Dann sollten Sie versuchen, die Datenbank-Engines der übergeordneten und untergeordneten Tabellen zu überprüfen. In meinem Fall wurde die Engine der übergeordneten Tabellen auf "MyISAM" gesetzt und durch Ändern in InnoDB behoben.

Hoffe das hilft anderen, die wie ich festsitzen.

Arun Shankar
quelle
1

Sie sollten kein Ondelete-Feld gegen eine Kaskade in der Datenbank einfügen.

Setzen Sie also das Feld onDelete auf RESTRICT

Viel Glück ♥

HamidReza Biglari
quelle
0

Noch ein seltsamer Fall, der mir diesen Fehler gab. Ich hatte meine Fremdschlüssel fälschlicherweise auf den ID-Primärschlüssel verwiesen. Dies wurde durch falsche Befehle zum Ändern der Tabelle verursacht. Ich habe dies herausgefunden, indem ich die Tabelle INFORMATION_SCHEMA abgefragt habe (siehe diese Antwort zum Stapelüberlauf).

Die Tabelle war so verwirrt, dass sie mit keinem ALTER TABLE-Befehl repariert werden konnte. Endlich ließ ich den Tisch fallen und rekonstruierte ihn. Dadurch wurde der Integritätsfehler beseitigt.

Vicky T.
quelle
0

Während Sie die userIDSpalte hinzugefügt haben , gibt es möglicherweise Daten für diese bestimmte Tabelle, die erstellt wurden, sodass sie den Standardwert von 0haben. Versuchen Sie, die Spalte ohne die hinzuzufügenNOT NULL

WTFZane
quelle
0

Ich habe auch die folgende Fehlermeldung erhalten: "Eine untergeordnete Zeile kann nicht hinzugefügt oder aktualisiert werden: Eine Fremdschlüsseleinschränkung schlägt fehl." Ich habe den Fehler beim Hinzufügen einer neuen Zeile zur übergeordneten Tabelle erhalten

Das Problem bestand darin, dass die Fremdschlüsseleinschränkung in der übergeordneten Tabelle anstelle der untergeordneten Tabelle definiert wurde.

Nadir Latif
quelle
0

Wenn Sie den MySQL-Index oder die Beziehung zwischen Tabellen verwenden, löschen Sie zuerst die Spalten (zum Beispiel: city_id) und erstellen neue Spalten mit demselben Namen (zum Beispiel: city_id). Versuchen Sie es dann erneut ...

Mahmut Aydın
quelle
0

Gibt es vorhandene Daten in der Tabelle? Versuchen Sie in diesem Fall, alle Daten in der Tabelle zu löschen, in der Sie einen Fremdschlüssel hinzufügen möchten. Führen Sie dann den Code erneut aus (fügen Sie einen Fremdschlüssel hinzu).

Ich bin so oft auf dieses Problem gestoßen. Dieses Löschen aller Daten in der Tabelle funktioniert, wenn Sie einer vorhandenen Tabelle einen Fremdschlüssel hinzufügen möchten.

Hoffe das funktioniert :)

Noldy
quelle
0

Löschen Sie die Indizes des UserID-Felds von Tabelle2. Es passt zu mir

Anton
quelle
-1

Die Fremdschlüsseleinschränkung der untergeordneten Tabelle schlägt fehl

Dieses Problem kann aus folgenden Gründen auftreten:

Wenn Sie dies in Spring mvc tun, müssen Sie den ID-Typ explizit beschreiben, da MySQL manchmal den ID-Typ nicht erkennt. Sie setzen also explizit wie in beiden Tabellen in Ihrer Entitätsklasse@GeneratedValue (strategy = GenerationType.IDENTITY)

Qaiser Iqbal Moeeni
quelle