web-dev-qa-db-fra.com

Impossible de supprimer ou de mettre à jour une ligne parente: une contrainte de clé étrangère échoue

En faisant:

DELETE FROM `jobs` WHERE `job_id` =1 LIMIT 1 

Il se trompe:

#1451 - Cannot delete or update a parent row: a foreign key constraint fails 
(paymesomething.advertisers, CONSTRAINT advertisers_ibfk_1 FOREIGN KEY 
(advertiser_id) REFERENCES jobs (advertiser_id))

Voici mes tables:

CREATE TABLE IF NOT EXISTS `advertisers` (
  `advertiser_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `password` char(32) NOT NULL,
  `email` varchar(128) NOT NULL,
  `address` varchar(255) NOT NULL,
  `phone` varchar(255) NOT NULL,
  `fax` varchar(255) NOT NULL,
  `session_token` char(30) NOT NULL,
  PRIMARY KEY (`advertiser_id`),
  UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;


INSERT INTO `advertisers` (`advertiser_id`, `name`, `password`, `email`, `address`, `phone`, `fax`, `session_token`) VALUES
(1, 'TEST COMPANY', '', '', '', '', '', '');

CREATE TABLE IF NOT EXISTS `jobs` (
  `job_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `advertiser_id` int(11) unsigned NOT NULL,
  `name` varchar(255) NOT NULL,
  `shortdesc` varchar(255) NOT NULL,
  `longdesc` text NOT NULL,
  `address` varchar(255) NOT NULL,
  `time_added` int(11) NOT NULL,
  `active` tinyint(1) NOT NULL,
  `moderated` tinyint(1) NOT NULL,
  PRIMARY KEY (`job_id`),
  KEY `advertiser_id` (`advertiser_id`,`active`,`moderated`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;


INSERT INTO `jobs` (`job_id`, `advertiser_id`, `name`, `shortdesc`, `longdesc`, `address`, `active`, `moderated`) VALUES
(1, 1, 'TEST', 'TESTTEST', 'TESTTESTES', '', 0, 0);

ALTER TABLE `advertisers`
  ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) REFERENCES `jobs` (`advertiser_id`);
126
steven

En l'état, vous devez supprimer la ligne de la table annonceurs avant de pouvoir supprimer la ligne de la table des travaux référencée. Ce:

ALTER TABLE `advertisers`
  ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) 
      REFERENCES `jobs` (`advertiser_id`);

... est en fait le contraire de ce que cela devrait être. En l'état actuel des choses, cela signifie que vous devriez avoir un enregistrement dans la table des travaux avant les annonceurs. Donc, vous devez utiliser:

ALTER TABLE `jobs`
  ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) 
      REFERENCES `advertisers` (`advertiser_id`);

Une fois que vous corrigez la relation de clé étrangère, votre instruction delete fonctionnera.

83
OMG Ponies

Le moyen le plus simple serait de désactiver la vérification de la clé étrangère. effectuez les modifications puis réactivez la vérification de la clé étrangère.

SET FOREIGN_KEY_CHECKS=0; -- to disable them
SET FOREIGN_KEY_CHECKS=1; -- to re-enable them
206
Alino Manzi

Sous votre conception actuelle (éventuellement défectueuse), vous devez supprimer la ligne de la table annonceurs avant / vous pouvez supprimer la ligne de la table des tâches à laquelle elle fait référence.

Vous pouvez également configurer votre clé étrangère de telle sorte qu'une suppression dans la table parent entraîne la suppression automatique des lignes des tables enfants. Cela s'appelle une suppression en cascade. Cela ressemble à quelque chose comme ça:

ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1`
FOREIGN KEY (`advertiser_id`) REFERENCES `jobs` (`advertiser_id`)
ON DELETE CASCADE;

Cela dit, comme d’autres l’ont déjà fait remarquer, votre clé étrangère a le sentiment qu’elle devrait être inversée car la table annonceurs contient réellement la clé primaire et la table des emplois contient la clé étrangère. Je voudrais le réécrire comme ceci:

ALTER TABLE `jobs`
ADD FOREIGN KEY (`advertiser_id`) REFERENCES `advertisers` (`advertiser_id`);

Et la suppression en cascade ne sera pas nécessaire.

29
Asaph

Si vous voulez supprimer une table, vous devez exécuter la requête suivante en une seule étape

SET FOREIGN_KEY_CHECKS = 0; DROP TABLE nom_table;

15
Abin John

Je pense que votre clé étrangère est en arrière. Essayer:

ALTER TABLE 'jobs'
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) REFERENCES `advertisers` (`advertiser_id`)
6
Tom H

Si plusieurs jobs ont le même annonceur_annonceur, votre clé étrangère doit être:

ALTER TABLE `jobs`
ADD CONSTRAINT `advertisers_ibfk_1` 
FOREIGN KEY (`advertiser_id`) 
REFERENCES `advertisers` (`advertiser_id`);

Sinon (si c'est l'inverse dans votre cas), si vous souhaitez que les lignes de l'annonceur soient automatiquement supprimées si la ligne du travail est supprimée, ajoutez l'option "ON DELETE CASCADE" à votre clé étrangère.

ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1` 
FOREIGN KEY (`advertiser_id`) 
REFERENCES `jobs` (`advertiser_id`);
ON DELETE CASCASE

Check out Contraintes de clé étrangère

3
Rashmi Pandit

Lorsque vous créez une base de données ou créez des tables 

Vous devriez ajouter cette ligne en haut du script, créer une base de données ou une table.

SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=1;

Maintenant, vous voulez supprimer les enregistrements de la table? alors vous écrivez comme

SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=1;
DELETE FROM `jobs` WHERE `job_id` =1 LIMIT 1

Bonne chance!

2
Quy Le

J'ai eu ce problème dans laravel migration too 
l'ordre des tables de suppression dans la méthode down () est important

Schema::dropIfExists('groups');
Schema::dropIfExists('contact');

peut ne pas fonctionner, mais si vous modifiez l'ordre, cela fonctionne.

Schema::dropIfExists('contact');
Schema::dropIfExists('groups');
2
Amin

Que diriez-vous de cette alternative que j’avais utilisée: autoriser la clé étrangère à êtreNULLpuis choisir ON DELETE SET NULL .

Personnellement, je préfère utiliser "ON UPDATE CASCADE" ainsi que "ON DELETE SET NULL" pour éviter les complications inutiles, mais vous voudrez peut-être une approche différente de votre configuration. De plus, les valeurs de clé étrangère NULL'ing peuvent entraîner des complications, car vous ne saurez pas exactement ce qui s'est passé là-bas. Ce changement doit donc être en relation étroite avec le fonctionnement de votre code d'application.

J'espère que cela t'aides.

1
Marius Cucuruz

Vous devez le supprimer par ordre Il existe des dépendances dans les tables 

1
Ran Adler

Vous pouvez créer un déclencheur pour supprimer les lignes référencées avant la suppression du travail.

    DELIMITER $$
    CREATE TRIGGER before_jobs_delete 
        BEFORE DELETE ON jobs
        FOR EACH ROW 
    BEGIN
        delete from advertisers where advertiser_id=OLD.advertiser_id;
    END$$
    DELIMITER ;
0
Patch92

Le principal problème de cet erorr Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails est qu’il ne vous permet pas de savoir quelle table contient l’échec de FK, il est donc difficile de résoudre le conflit.

Si vous utilisez MySQL ou similaire, j'ai découvert que vous pouvez créer un diagramme ER pour votre base de données, vous pouvez alors examiner et supprimer en toute sécurité tout conflit générant l'erreur.

  1. Utiliser MySQL Workbench
  2. Cliquez sur Base de données -> Ingénierie inverse
  3. Sélectionnez le bon connection
  4. Jusqu'à la fin, n'oubliez pas de sélectionner database & tables à examiner
  5. Maintenant vous avez le diagramme ER, vous pouvez voir quelle table a un conflit FK
0
Ng Sek Long

Peut-être devriez-vous essayer ON DELETE CASCADE

0
UFOman

si vous avez besoin d’assistance client le plus tôt possible et n’avez pas accès à 

FOREIGN_KEY_CHECKS

afin que l'intégrité des données puisse être désactivée:

1) supprimer la clé étrangère

ALTER TABLE `advertisers` 
DROP FOREIGN KEY `advertisers_ibfk_1`;

2) activer votre opération de suppression via sql ou api

3) rajouter la clé étrangère au schéma

ALTER TABLE `advertisers`
  ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) REFERENCES `jobs` (`advertiser_id`);

cependant, il s'agit d'un correctif, vous assumez donc tous les risques, car le principal défaut de cette approche est qu'il est nécessaire par la suite de conserver manuellement l'intégrité des données.

0
Oleksii Kyslytsyn