Cela semble être une erreur commune, mais pour ma vie, je ne peux pas comprendre cela.
J'ai un ensemble de tables utilisateur InnoDB dans MySQL qui sont liées entre elles via une clé étrangère; la table parent user
et un ensemble de tables enfants stockant des adresses de messagerie, des actions, etc. Elles sont toutes liées à la table parent user
par une clé étrangère, uid
, toutes les clés parent et enfant étant int(10)
.
Toutes les tables enfants ont une valeur uid
avec une contrainte de clé étrangère pointant vers user.uid
et définie sur ON DELETE CASCADE
et ON UPDATE CASCADE
.
Lorsque je supprime un utilisateur de user
, toutes les entrées d'enfants contraintes sont supprimées. Cependant, lorsque je tente de mettre à jour une valeur user.uid
, l'erreur suivante est générée, plutôt que de transférer en cascade la modification uid
aux tables enfants:
#1452 - Cannot add or update a child row: a foreign key constraint fails (`accounts`.`user_email`, CONSTRAINT `user_email_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE)
J'ai le sentiment qu'il me manque quelque chose d'évident ici. Supprimer la contrainte de clé avec user_email
et tenter de mettre à jour la valeur dans user
entraîne la même erreur, mais pour la table enfant user
alphabétique suivante, donc je ne crois pas qu'il s'agisse d'une erreur spécifique à la table.
MODIFIER:
Ajout dans les résultats de SHOW ENGINE INNODB STATUS
:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
121018 22:35:41 Transaction:
TRANSACTION 0 5564387, ACTIVE 0 sec, process no 1619, OS thread id 2957499248 updating or deleting, thread declared inside InnoDB 499
mysql tables in use 1, locked 1
17 lock struct(s), heap size 2496, 9 row lock(s), undo log entries 2
MySQL thread id 3435659, query id 24068634 localhost root Updating
UPDATE `accounts`.`user` SET `uid` = '1' WHERE `user`.`uid` = 306
Foreign key constraint fails for table `accounts`.`user_email`:
,
CONSTRAINT `user_email_ibfk_2` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE
Trying to add in child table, in index `uid` Tuple:
DATA Tuple: 2 fields;
...
A bunch of hex code
But in parent table `accounts`.`user`, in index `PRIMARY`,
the closest match we can find is record:
...
A bunch of hex code
Dans une tâche indépendante, j’ai récemment évoqué notre base de données MySQL dans MySQL Workbench , et lors de l’affichage des relations entre les tables ci-dessus, j’ai remarqué des relations «en double» et/ou erronées que pas dans PHPMyAdmin FWIW). La suppression de ces relations supplémentaires a éclairci le problème immédiatement.
J'ai résolu mes problèmes ' de clé étrangère qui échouaient ' en ajoutant le code suivant au début du code SQL (il s'agissait de l'importation de valeurs dans une table)
SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT;
SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS;
SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION;
SET NAMES utf8;
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0;
Puis en ajoutant ce code à la fin du fichier
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT;
SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS;
SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION;
SET SQL_NOTES=@OLD_SQL_NOTES;
Puisque vous n'avez pas donné de définitions de table, c'est difficile à deviner. Mais il semble que vous tentiez de modifier la clé étrangère dans la table enfant. Autant que je sache, c'est illégal, vous pouvez le modifier depuis le parent, mais pas la table enfant.
Considérons cet exemple:
CREATE TABLE parent (
parent_id INT NOT NULL,
parent_data int,
PRIMARY KEY (parent_id)
) ENGINE=INNODB;
CREATE TABLE child1 (
child1_id INT,
child1_data INT,
fk_parent_id INT,
INDEX par_ind1 (fk_parent_id),
FOREIGN KEY (fk_parent_id)
REFERENCES parent(parent_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=INNODB;
CREATE TABLE child2 (
child2_id INT,
child2_data INT,
fk_parent_id INT,
INDEX par_ind2 (fk_parent_id),
FOREIGN KEY (fk_parent_id)
REFERENCES parent(parent_id)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=INNODB;
INSERT INTO parent
(parent_id, parent_data)
VALUES
(1, 11),
(2, 12);
INSERT INTO child1
(child1_id, child1_data, fk_parent_id)
VALUES
(101, 1001, 1),
(102, 1002, 1),
(103, 1003, 1),
(104, 1004, 2),
(105, 1005, 2);
INSERT INTO child2
(child2_id, child2_data, fk_parent_id)
VALUES
(106, 1006, 1),
(107, 1007, 1),
(108, 1008, 1),
(109, 1009, 2),
(110, 1010, 2);
Alors ceci est permis:
UPDATE parent
SET parent_id = 3 WHERE parent_id = 2;
SELECT * FROM parent;
SELECT * FROM child1;
SELECT * FROM child2;
Mais ce n'est pas le cas, car cela modifie le fk parent de la table enfant:
UPDATE child1
SET fk_parent_id = 4 WHERE fk_parent_id = 1;
Il obtient une erreur très similaire à votre erreur:
Cannot add or update a child row: a foreign key constraint fails (`db_2_b43a7`.`child1`, CONSTRAINT `child1_ibfk_1` FOREIGN KEY (`fk_parent_id`) REFERENCES `parent` (`parent_id`) ON DELETE CASCADE ON UPDATE CASCADE):
J'avais affronté le même problème en créant des contraintes étrangères sur la table. Le moyen le plus simple de résoudre ce problème consiste à commencer par sauvegarder la table parent et la table enfant, puis à la tronquer, puis à essayer de créer une relation. espérons que cela résoudra le problème.
Une telle erreur lors de la mise à jour peut être due à la différence entre le jeu de caractères et le classement. Assurez-vous donc qu'ils sont identiques pour les deux tables.