ERREUR 1452: impossible d'ajouter ou de mettre à jour une ligne enfant: une contrainte de clé étrangère échoue


132

J'ai créé des tables dans MySQL Workbench comme indiqué ci-dessous:

Tableau 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;

Table 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;

et table 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;

donc quand j'essaye d'insérer des valeurs dans la ORDRELINJEtable j'obtiens:

Code d'erreur: 1452. Impossible d'ajouter ou de mettre à jour une ligne enfant: une contrainte de clé étrangère échoue ( srdjank. Ordrelinje, CONSTRAINT Ordrelinje_fkFOREIGN KEY ( Ordre) REFERENCES Ordre( OrdreID))

J'ai vu les autres articles sur ce sujet, mais pas de chance. Est-ce que je supervise quelque chose ou une idée de ce que je dois faire?


Réponses:


172

Tiré de l' utilisation des contraintes FOREIGN KEY

Les relations de clé étrangère impliquent une table parent qui contient les valeurs de données centrales et une table enfant avec des valeurs identiques pointant vers son parent. La clause FOREIGN KEY est spécifiée dans la table enfant.

Il rejettera toute opération INSERT ou UPDATE qui tente de créer une valeur de clé étrangère dans une table enfant s'il n'y a pas de valeur de clé candidate correspondante dans la table parent.

Donc, votre erreur Error Code: 1452. Cannot add or update a child row: a foreign key constraint failssignifie essentiellement que vous essayez d'ajouter une ligne à votre Ordrelinjetable pour laquelle aucune ligne correspondante (OrderID) n'est présente dans la Ordretable.

Vous devez d'abord insérer la ligne dans votre Ordretableau.


Ou pouvons-nous supprimer la clé étrangère puis ajouter une clé étrangère après l'insertion de données?
Vamsi Pavan Mahesh

@VamsiPavanMahesh, NON, car même si vous faites cela; votre création de clé foriegn échouera avec le même type d'erreur car il y aura une discordance de données clés.
Rahul

4
En termes simples, si les enfants ont des identifiants de parents définis, ces parents doivent exister. Et je pensais que ma syntaxe était incorrecte ... Cela m'a beaucoup aidé. Merci!
wst

2
Qu'en est-il des relations optionnelles?
Hamed Hamedi

40

Vous obtenez cette vérification de contrainte car la Ordretable n'a pas de référence OrdreIDfournie dans la commande d'insertion.

Pour insérer une valeur dans Ordrelinje, vous devez d'abord entrer la valeur dans le Ordretableau et l'utiliser OrdreIDdans le Orderlinjetableau.

Ou vous pouvez supprimer la contrainte non nulle et y insérer une valeur NULL.


30

Vous devez supprimer les données de la table enfant qui n'ont pas de valeur de clé étrangère correspondante à la clé primaire de la table parent. Ou supprimer toutes les données de la table enfant puis insérer de nouvelles données ayant la même valeur de clé étrangère que la clé primaire dans la table parent . Cela devrait fonctionner . Ici aussi une vidéo youtube


1
C'est correct, avant d'insérer des données dans le tableau croisé dynamique (celui ayant des contraintes CASCADE), vous devez insérer des données dans les tables parent. par exemple 1ère table - autorisations; 2e tableau - rôles; 3e table - permission_role; Donc 1ère insertion dans la table des permissions, 2ème insertion dans la table des rôles et enfin insertion dans la table permission_role.
Deepak Panwar

25

Le problème est lié à la contrainte FOREIGN KEY. Par défaut (SET FOREIGN_KEY_CHECKS = 1). L'option FOREIGN_KEY_CHECKS spécifie s'il faut ou non vérifier les contraintes de clé étrangère pour les tables InnoDB. MySQL - SET FOREIGN_KEY_CHECKS

Nous pouvons définir la vérification de la clé étrangère comme désactivée avant d'exécuter la requête. Désactivez la clé étrangère .

Exécutez l'une de ces lignes avant d'exécuter votre requête, puis vous pouvez exécuter votre requête avec succès. :)

1) Pour la session (recommandé)

SET FOREIGN_KEY_CHECKS=0;

2) à l'échelle mondiale

SET GLOBAL FOREIGN_KEY_CHECKS=0;

19

Cette erreur se produit généralement car nous avons des valeurs dans le champ de référence de la table enfant, qui n'existent pas dans le champ référencé / candidat de la table parent.

Parfois, nous pouvons obtenir cette erreur lorsque nous appliquons des contraintes de clé étrangère à des tables existantes, contenant déjà des données . Certaines des autres réponses suggèrent de supprimer complètement les données de la table enfant, puis d'appliquer la contrainte. Cependant, ce n'est pas une option lorsque nous avons déjà des données de travail / production dans la table enfant. Dans la plupart des scénarios, nous devrons mettre à jour les données de la table enfant (au lieu de les supprimer).

Maintenant, nous pouvons utiliser Left Joinpour trouver toutes ces lignes dans la table enfant, qui n'a pas de valeurs correspondantes dans la table parent. La requête suivante serait utile pour récupérer ces lignes non correspondantes:

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

Désormais, vous pouvez généralement effectuer une (ou plusieurs) des étapes suivantes pour corriger les données.

  1. En fonction de votre "logique métier", vous devrez mettre à jour / faire correspondre ces valeurs sans correspondance avec les valeurs existantes dans la table parent. Vous devrez peut-être parfois les définir nullégalement.
  2. Supprimez ces lignes dont les valeurs ne correspondent pas.
  3. Ajoutez de nouvelles lignes dans votre table parent, correspondant aux valeurs sans correspondance dans la table enfant.

Une fois les données corrigées, nous pouvons appliquer la contrainte de clé étrangère à l'aide de la ALTER TABLEsyntaxe.


Je supprime toutes les données de la table, puis j'ajoute la clé étrangère, elle a été ajoutée merci
Sumit Kumar Gupta

4

dans la table de clé étrangère a une valeur qui n'appartient pas à la table de clé primaire qui sera liée, vous devez donc d'abord supprimer toutes les données / ajuster la valeur de votre table de clé étrangère en fonction de la valeur qui se trouve dans votre clé primaire


3

J'avais ce problème même si ma table parent avait toutes les valeurs auxquelles je faisais référence dans ma table enfant. Le problème semblait être que je ne pouvais pas ajouter plusieurs références enfants à une seule clé étrangère. En d'autres termes, si j'avais cinq lignes de données référencées à la même clé étrangère, MySQL ne me permettait de télécharger que la première ligne et me donnait l'erreur 1452.

Ce qui a fonctionné pour moi a été de taper le code "SET GLOBAL FOREIGN_KEY_CHECKS = 0". Après cela, j'ai fermé MySQL, puis je l'ai redémarré et j'ai pu télécharger toutes mes données sans erreur. J'ai alors tapé "SET GLOBAL FOREIGN_KEY_CHECKS = 1" pour remettre le système à la normale bien que je ne sois pas entièrement sûr de ce que fait FOREIGN_KEY_CHECKS. J'espère que cela t'aides!


N'est-ce pas exactement ce qui a déjà été suggéré dans la réponse postée par @ Mr-Faizan? Sinon, veuillez expliquer ce que votre réponse ajoute.
Adrian Mole

2

Cela peut être résolu en insérant d'abord les enregistrements respectifs dans la table Parent, puis nous pouvons insérer des enregistrements dans la colonne respective de la table Child. Vérifiez également le type de données et la taille de la colonne. Elle doit être identique à la colonne de la table parent, même le moteur et le classement doivent également être identiques. ESSAYE ÇA! C'est ainsi que j'ai résolu le mien. Corrigez-moi si je me trompe.


1

Votre ORDRELINJEtable est liée à une ORDERtable en utilisant une contrainte de clé étrangère constraint Ordrelinje_fk foreign key(Ordre) references Ordre(OrdreID)selon quelle Ordre int NOT NULL,colonne de table ORDRELINJEdoit correspondre à n'importe quelle Ordre int NOT NULL,colonne de ORDERtable.

Maintenant, ce qui se passe ici, c'est que lorsque vous insérez une nouvelle ligne dans la ORDRELINJEtable, selon la contrainte fk, Ordrelinje_fkil vérifie ORDERsi la table OrdreIDest présente ou non et comme elle ne correspond à aucun OrderId, le compilateur se plaint de la violation de clé étrangère. C'est la raison pour laquelle vous obtenez cette erreur.

La clé étrangère est la clé primaire de l'autre table que vous utilisez dans n'importe quelle table pour établir un lien entre les deux. Cette clé est liée par la contrainte de clé étrangère que vous spécifiez lors de la création de la table. Toute opération sur les données ne doit pas violer cette contrainte. La violation de cette contrainte peut entraîner des erreurs comme celle-ci.

J'espère que j'ai été clair.


1

Lors de l'insertion des valeurs d'attribut de clé étrangère, vérifiez d'abord le type d'attribut, ainsi que la valeur d'attribut de clé primaire dans la relation parent, si les valeurs de la relation parent correspondent, vous pouvez facilement insérer / mettre à jour les valeurs d'attribut enfant.


1

vous devez ajouter des données de REFERENCES KEY dans PRIMARY TABLE à FOREIGN KEY dans CHILD TABLE
cela signifie ne pas ajouter de données aléatoires à la clé étrangère ، utiliser simplement les données de la clé primaire qui sont accessibles

description des données dans la clé étrangère


1

Cela m'a aidé après avoir lu @ Mr-Faizan et d'autres réponses.

Décochez la case "Activer les vérifications de clé étrangère"

dans phpMyAdmin et appuyez sur la requête. Je ne connais pas WorkBench mais les autres réponses pourraient vous aider.


0

vous devez insérer au moins un raw dans chaque table (celles sur lesquelles vous voulez que les clés étrangères pointent) puis vous pouvez insérer ou mettre à jour les valeurs des clés étrangères


0

mal insérez ceci ici: mon cas essayait de créer un semblable pour un poste qui à force d'exister; lors de la validation dans la base de données, l'erreur a été générée. La solution était de créer d'abord le message puis de l'aimer. d'après ce que j'ai compris, si le post_id devait être enregistré dans la table des likes, il fallait d'abord vérifier avec la table des messages pour vérifier l'existence. J'ai trouvé mieux de l'avoir de cette façon car c'est plus logique pour moi de cette façon.


0

Lorsque vous utilisez une clé étrangère , l' ordre des colonnes doit être le même pour l' insertion .

Par exemple, si vous ajoutez (userid, password)à table1 de table2 puis de table2 ordre doit être la même (userid, password)et pas comme (password,userid)useridest la clé étrangère dans table2 de table1 .


0

Le problème se produit car vous définissez la clé étrangère dans la table enfant après avoir inséré des données dans la table enfant.

Essayez de supprimer toutes les données de la table enfant, puis définissez la clé étrangère et ensuite ajoutez / insérez les données dans la table, cela fonctionnera.


0

vérifiez le non. de l'enregistrement dans la table parent qui correspond à la table enfant et également la clé primaire doit correspondre à la référence de clé étrangère. Cela fonctionne pour moi.


-4

Son fonctionnement à 100% ...

ERREUR 1452: Impossible d'ajouter ou de mettre à jour une ligne enfant: une contrainte de clé étrangère échoue .... si ce type d'erreur se produit: alors tout d'abord allez dans cette table et vérifiez le paramètre> si le moteur est: InnoDB puis changez-le en MyISAM

(et supprimer les références à la contrainte étrangère)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.