Kan een bovenliggende rij niet verwijderen of bijwerken: een Buitenlandse Key Constraint mislukt

Bij het doen:

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

IT-fouten:

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

Hier zijn mijn tabellen:

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

Antwoord 1, autoriteit 100%

Zoals het is, moet u de rij uit de tabel met adverteerders verwijderen voordat u de rij in de tabel met vacatures waarnaar deze verwijst, kunt verwijderen. Dit:

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

…is eigenlijk het tegenovergestelde van wat het zou moeten zijn. Zoals het is, betekent dit dat je een record in de banentabel moet hebben voor de adverteerders. Dus je moet gebruiken:

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

Zodra u de relatie met de refererende sleutel heeft gecorrigeerd, werkt uw verwijderopdracht.


Antwoord 2, autoriteit 98%

De eenvoudige manier zou zijn om de externe sleutelcontrole uit te schakelen; breng de wijzigingen aan en schakel vervolgens de buitenlandse sleutelcontrole weer in.

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

Antwoord 3, autoriteit 34%

In uw huidige (mogelijk gebrekkige) ontwerp moet u de rij uit de tabel met adverteerders verwijderen voordatu de rij in de vacaturetabel waarnaar deze verwijst, kunt verwijderen.

Als alternatief kunt u uw externe sleutel zo instellen dat een verwijdering in de bovenliggende tabel ervoor zorgt dat rijen in onderliggende tabellen automatisch worden verwijderd. Dit wordt een trapsgewijze verwijdering genoemd. Het ziet er ongeveer zo uit:

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

Dat gezegd hebbende, zoals anderen al hebben opgemerkt, voelt het alsof uw externe sleutel andersom zou moeten zijn, aangezien de tabel met adverteerders echt de primaire sleutel bevat en de tabel met vacatures de externe sleutel. Ik zou het als volgt herschrijven:

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

En de trapsgewijze verwijdering is niet nodig.


Antwoord 4, autoriteit 13%

Als u een tabel wilt verwijderen, moet u de volgende query in één stap uitvoeren

SET FOREIGN_KEY_CHECKS=0;
DROP TABLE table_name;


Antwoord 5, autoriteit 12%

Ik heb de oplossing geprobeerd die door @Alino Manzi wordt genoemd, maar het werkte niet voor mij op de WordPress-gerelateerde tabellen met wpdb.

vervolgens wijzigde ik de code zoals hieronder en het werkte

SET FOREIGN_KEY_CHECKS=OFF; //disabling foreign key
//run the queries which are giving foreign key errors
SET FOREIGN_KEY_CHECKS=ON; // enabling foreign key

Antwoord 6, autoriteit 11%

Schakel de externe-sleutelcontrole uit en breng de wijzigingen aan en schakel vervolgens de externe-sleutelcontrole weer in.

SET FOREIGN_KEY_CHECKS=0; -- to disable them
DELETE FROM `jobs` WHERE `job_id` = 1 LIMIT 1 
SET FOREIGN_KEY_CHECKS=1; -- to re-enable them

Antwoord 7, autoriteit 5%

Ik denk dat uw externe sleutel achterstevoren is. Probeer:

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

Antwoord 8, autoriteit 4%

Als er meer dan één vacature is met dezelfde adverteerder_id, moet uw externe sleutel zijn:

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

Anders (als het in uw geval andersom is), als u wilt dat de rijen in de adverteerder automatisch worden verwijderd als de rij in de taak wordt verwijderd, voegt u de optie ‘ON DELETE CASCADE’ toe aan het einde van uw refererende sleutel:

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

Bekijk Foreign Key-beperkingen


Antwoord 9, autoriteit 2%

Je moet het op bestelling verwijderen
Er zijn afhankelijkheid in de tabellen


Antwoord 10, autoriteit 2%

Wanneer u een database aanmaakt of tabellen maakt

Je moet die regel bovenaan toevoegen script database of tabel maken

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

Wilt u nu records uit de tabel verwijderen? dan schrijf je als

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

Veel succes!


Antwoord 11, autoriteit 2%

Wat dacht je van dit alternatief dat ik heb gebruikt: laat de externe sleutel NULLzijn en kies vervolgens ON DELETE SET NULL.

Persoonlijk geef ik er de voorkeur aan om zowel “ON UPDATE CASCADE” als “ON DELETE SET NULL” te gebruiken om onnodige complicaties te voorkomen, maar bij uw installatie wilt u misschien een andere aanpak. Ook kunnen NULL-waarden voor externe sleutels tot complicaties leiden, omdat u niet weet wat daar precies is gebeurd. Deze wijziging moet dus nauw verband houden met hoe uw applicatiecode werkt.

Hopelijk helpt dit.


Antwoord 12, autoriteit 2%

Ik had dit probleem ook bij laravel-migratie
de volgorde van de neerzettabellen in de methode down() doet er toe

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

werkt misschien niet, maar als je de volgorde wijzigt, werkt het wel.

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

Antwoord 13

als u de klant zo snel mogelijk moet ondersteunen en geen toegang heeft tot

FOREIGN_KEY_CHECKS

zodat de gegevensintegriteit kan worden uitgeschakeld:

1) externe sleutel verwijderen

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

2) activeer uw verwijderingshandeling via sql of api

3) voeg de externe sleutel weer toe aan het schema

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

het is echter een hot-fix, dus het is op eigen risico, omdat het belangrijkste nadeel van een dergelijke aanpak is dat het achteraf nodig is om de gegevensintegriteit handmatig te behouden.


Antwoord 14

Het belangrijkste probleem met deze fout Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint failsis dat het u niet laat weten welke tabel< bevatde FK-fout, dus het is moeilijk om het conflict op te lossen.

Als je MySQL of iets dergelijks gebruikt, heb ik ontdekt dat je een ER-diagramvoor uw database, dan kunt u eventuele conflicten die de fout veroorzaken, bekijken en veilig verwijderen.

  1. Gebruik MySQL-werkbank
  2. Klik op Database -> Reverse-engineering
  3. Selecteer een juiste connection
  4. Vergeet niet om tot het einde databasete selecteren & tablesdie moeten worden onderzocht
  5. Nu je het ER-diagram hebt, kun je zien welke tabel een FK-conflict heeft

Antwoord 15

U kunt een trigger maken om de rijen waarnaar wordt verwezen te verwijderen voordat u de taak verwijdert.

   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 ;

Antwoord 16

In principe,
De reden achter dit type fout probeert u uiteindelijk een tupple te verwijderen die een primaire sleutel heeft (root-tabel) & amp; Die primaire sleutel wordt in de kindertafel gebruikt als een buitenlandse sleutel.
In dit scenario om bovenliggende tabelgegevens te verwijderen, moet u kindertabelgegevens verwijderen (waarin de buitenlandse sleutel wordt gebruikt).
Bedankt


Antwoord 17

Misschien moet u proberen in Cascade


Antwoord 18

Dit gebeurde mij ook en vanwege een afhankelijkheid en referentie van andere tabellen, kon ik het item niet verwijderen. Wat ik deed, is een Delete-kolom (van Type Boolean) aan de tafel toegevoegd. De waarde op dat gebied liet zien of het item is gemarkeerd voor het verwijderen of niet. Indien gemarkeerd voor het verwijderen, niet ophalen / gebruiken; Gebruik het anders.

Other episodes