J'ai un petit problème étrange. J'essaie d'ajouter une clé étrangère à une table qui en fait référence à une autre, mais elle échoue pour une raison quelconque. Avec ma connaissance limitée de MySQL, la seule chose qui pourrait être suspecte est qu'il existe une clé étrangère sur une table différente référençant celle que j'essaie de référencer.
J'ai fait une SHOW CREATE TABLE
requête sur les deux tables, sourcecodes_tags
c'est la table avec la clé étrangère, sourcecodes
c'est la table référencée.
CREATE TABLE `sourcecodes` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) unsigned NOT NULL,
`language_id` int(11) unsigned NOT NULL,
`category_id` int(11) unsigned NOT NULL,
`title` varchar(40) CHARACTER SET utf8 NOT NULL,
`description` text CHARACTER SET utf8 NOT NULL,
`views` int(11) unsigned NOT NULL,
`downloads` int(11) unsigned NOT NULL,
`time_posted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `language_id` (`language_id`),
KEY `category_id` (`category_id`),
CONSTRAINT `sourcecodes_ibfk_3` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sourcecodes_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sourcecodes_ibfk_2` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
CREATE TABLE `sourcecodes_tags` (
`sourcecode_id` int(11) unsigned NOT NULL,
`tag_id` int(11) unsigned NOT NULL,
KEY `sourcecode_id` (`sourcecode_id`),
KEY `tag_id` (`tag_id`),
CONSTRAINT `sourcecodes_tags_ibfk_1` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
C'est le code qui génère l'erreur:
ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE
Réponses:
Il est fort probable que votre
sourcecodes_tags
table contienne dessourcecode_id
valeurs qui n'existent plus dans votresourcecodes
table. Vous devez d'abord vous en débarrasser.Voici une requête qui peut trouver ces ID:
la source
UPDATE sourcecodes_tags SET sourcecode_id = NULL WHERE sourcecode_id NOT IN (SELECT id FROM sourcecodes)
devrait aider à se débarrasser de ces identifiants. Ou sinull
n'est pas autorisé danssourcecode_id
, supprimez ces lignes ou ajoutez ces valeurs manquantes ausourcecodes
tableau.SELECT Tchild.id FROM Tchild INNER JOIN Tmain ON Tmain.id = Tchild.fk_id WHERE Tmain.id IS NULL
ne retourne rien, donc le problème est ailleurs!?UPDATE `homestead`.`automations` SET `deleted_at`=NULL WHERE deleted_at IS NOT NULL;
, ce qui ne comportait pas du tout de clé étrangère, donc j'étais confus. Mais le fait qu'il manquait à ma table de contacts certains enregistrements auxquels la table d'automatisations faisait référence l'a amenée à lancer ce "Code d'erreur: 1452. Impossible d'ajouter ou de mettre à jour une ligne enfant: une contrainte de clé étrangère échoue".J'ai eu le même problème avec ma base de données MySQL mais finalement, j'ai obtenu une solution qui fonctionnait pour moi.
Puisque dans ma table tout allait bien du point de vue mysql (les deux tables devraient utiliser le moteur InnoDB et le type de données de chaque colonne devrait être du même type qui participe à la contrainte de clé étrangère).
La seule chose que j'ai faite a été de désactiver la vérification de la clé étrangère et de l'activer plus tard après avoir effectué l'opération de clé étrangère.
Étapes que j'ai prises:
la source
Utilisez
NOT IN
pour trouver où les contraintes contraignent :donc, plus précisément:
EDIT:
IN
et lesNOT IN
opérateurs sont connus pour être beaucoup plus rapides que lesJOIN
opérateurs, ainsi que beaucoup plus faciles à construire et à répéter.la source
Tronquez les tables, puis essayez d'ajouter la contrainte FK .
Je sais que cette solution est un peu gênante mais elle fonctionne à 100%. Mais je suis d'accord que ce n'est pas une solution idéale pour résoudre un problème, mais j'espère que cela aide.
la source
Pour moi, ce problème était un peu différent et super facile à vérifier et à résoudre.
Vous devez vous assurer que LES DEUX de vos tables sont InnoDB. Si l'une des tables, à savoir la table de référence est un MyISAM, la contrainte échouera.
la source
Cela se produit également lorsque vous définissez une clé étrangère sur parent.id sur child.column si child.column a déjà une valeur de 0 et qu'aucune valeur parent.id n'est 0
Vous devez vous assurer que chaque colonne child.column est NULL ou a une valeur qui existe dans parent.id
Et maintenant que j'ai lu la déclaration que nous avons écrite, c'est ce qu'il valide.
la source
J'ai eu le même problème aujourd'hui. J'ai testé quatre choses, certaines d'entre elles ont déjà été mentionnées ici:
Y a-t-il des valeurs dans votre colonne enfant qui n'existent pas dans la colonne parent (à part NULL, si la colonne enfant est nullable)
Les colonnes enfant et parent ont-elles le même type de données?
Y a-t-il un index sur la colonne parent à laquelle vous faites référence? MySQL semble l'exiger pour des raisons de performances ( http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html )
Et celui-ci l'a résolu pour moi: les deux tables ont-elles un classement identique?
J'avais une table en UTF-8 et l'autre en iso-quelque chose. Ça n'a pas marché. Après avoir changé l'iso-table en classement UTF-8, les contraintes peuvent être ajoutées sans problème. Dans mon cas, phpMyAdmin n'a même pas montré la table enfant en iso-encoding dans la liste déroulante pour créer la contrainte de clé étrangère.
la source
Il semble qu'il y ait une valeur non valide pour la ligne de colonne 0 qui n'est pas une clé étrangère valide, donc MySQL ne peut pas lui assigner de contrainte de clé étrangère.
Vous pouvez suivre ces étapes:
Supprimez la colonne pour laquelle vous avez essayé de définir la contrainte FK.
Ajoutez-le à nouveau et définissez sa valeur par défaut sur NULL.
Essayez de définir à nouveau une contrainte de clé étrangère.
la source
J'aurais le même problème, j'ai vérifié les lignes de mes tables et j'ai trouvé qu'il y avait une incompatibilité avec la valeur des champs que je voulais définir une clé étrangère. J'ai corrigé ces valeurs, réessayé et le problème a été résolu.
la source
Je finis par supprimer toutes les données de ma table et j'exécute à nouveau alter. Ça marche. Pas la plus brillante, mais cela fait gagner beaucoup de temps, en particulier votre application est toujours en phase de développement sans aucune donnée client.
la source
essaye ça
la source
J'ai eu exactement le même problème environ trois fois. Dans chaque cas, c'était parce qu'un (ou plusieurs) de mes enregistrements n'était pas conforme à la nouvelle clé étrangère. Vous souhaiterez peut-être mettre à jour vos enregistrements existants pour respecter les contraintes de syntaxe de la clé étrangère avant d'essayer d'ajouter la clé elle-même. L'exemple suivant doit généralement isoler les enregistrements de problème:
répéter
AND (candidate key) <> (next proposed foreign key value)
dans votre requête pour chaque valeur de la clé étrangère.Si vous avez une tonne d'enregistrements, cela peut être difficile, mais si votre table est raisonnablement petite, cela ne devrait pas prendre trop de temps. Je ne suis pas super étonnant dans la syntaxe SQL, mais cela a toujours isolé le problème pour moi.
la source
Videz les données de vos tables et exécutez la commande. Ça va marcher.
la source
J'obtenais cette erreur lorsque j'utilisais Laravel et éloquent, essayer de créer un lien de clé étrangère provoquerait un 1452. Le problème était le manque de données dans la table liée.
Veuillez consulter ici un exemple: http://mstd.eu/index.php/2016/12/02/laravel-eloquent-integrity-constraint-violation-1452-foreign-key-constraint/
la source
Je préparais ces solutions et cet exemple peut aider.
Ma base de données a deux tables (email et carte de crédit) avec des clés primaires pour leurs identifiants. Une autre table (client) fait référence à ces identifiants de tables comme des clés étrangères. J'ai une raison d'avoir l'e-mail en dehors des données client.
J'insère d'abord les données de ligne pour les tables référencées (email, credit_card) puis vous obtenez l'ID pour chacune, ces ID sont nécessaires dans la troisième table (client).
Si vous n'insérez pas d'abord les lignes dans les tables référencées, MySQL ne pourra pas faire les correspondances lorsque vous insérez une nouvelle ligne dans la troisième table qui fait référence aux clés étrangères.
Si vous insérez d'abord les lignes référencées pour les tables référencées, puis la ligne qui fait référence aux clés étrangères, aucune erreur ne se produit.
J'espère que cela t'aides.
la source
Assurez-vous que la valeur est dans l'autre table, sinon vous obtiendrez cette erreur, dans la colonne correspondante affectée.
Donc, si une colonne est affectée à un ID de ligne d'une autre table, assurez-vous qu'il y a une ligne dans la table, sinon cette erreur apparaîtra.
la source
vous pouvez essayer cet exemple
Remarque: si vous utilisez phpmyadmin, décochez simplement Activer les vérifications de clés étrangères
comme exemple
j'espère que cette solution résout votre problème :)
la source
Il vous suffit de répondre à une question:
Votre table stocke-t-elle déjà des données? (Surtout le tableau comprenait une clé étrangère.)
Si la réponse est oui, alors la seule chose que vous devez faire est de supprimer tous les enregistrements, vous êtes alors libre d'ajouter n'importe quelle clé étrangère à votre table.
La raison pour laquelle vous ne pouvez pas ajouter de clé étrangère après la saisie de données est due à l'incohérence de la table, comment allez-vous gérer une nouvelle clé étrangère sur l'ancienne table remplie de données?
Si la réponse est non, suivez les autres instructions.
la source
devrait aider à se débarrasser de ces identifiants. Ou si
null
n'est pas autorisé danssourcecode_id
, supprimez ces lignes ou ajoutez ces valeurs manquantes ausourcecodes
tableau.la source
J'ai eu le même problème et j'ai trouvé une solution, en plaçant
NULL
au lieu deNOT NULL
sur la colonne de clé étrangère. Voici une requête:MySQL a exécuté cette requête!
la source
Dans mon cas, j'ai créé une nouvelle table avec la même structure, créé les relations avec les autres tables, puis extrait les données dans CSV de l'ancienne table qui a le problème, puis importé le CSV dans la nouvelle table et désactivé la vérification des clés étrangères et désactivé l'interruption de l'importation, toutes mes données sont insérées dans la nouvelle table qui n'a pas de problème avec succès, puis supprimées l'ancienne table.
Ça a marché pour moi.
la source