webentwicklung-frage-antwort-db.com.de

MySQL - Eine untergeordnete Zeile kann nicht hinzugefügt oder aktualisiert werden: Eine Fremdschlüsseleinschränkung schlägt fehl

Dies scheint ein häufiger Fehler zu sein, aber für mein Leben kann ich das nicht verstehen.

Ich habe eine Reihe von InnoDB-Benutzertabellen in MySQL, die über einen Fremdschlüssel miteinander verbunden sind. die übergeordnete user-Tabelle und eine Reihe von untergeordneten Tabellen, in denen E-Mail-Adressen, Aktionen usw. gespeichert werden. Diese sind alle durch einen Fremdschlüssel user an die übergeordnete uid-Tabelle gebunden, wobei alle übergeordneten und untergeordneten Schlüssel int(10) sind.

Alle untergeordneten Tabellen haben einen uid-Wert mit einer Fremdschlüsseleinschränkung, die auf user.uid zeigt und auf ON DELETE CASCADE und ON UPDATE CASCADE eingestellt ist. 

Wenn ich einen Benutzer aus user lösche, werden alle untergeordneten beschränkten Einträge entfernt. Wenn ich jedoch versuche, einen user.uid-Wert zu aktualisieren, führt dies zu dem folgenden Fehler, anstatt die uid-Änderung in die untergeordneten Tabellen zu verschieben:

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

Ich habe das Gefühl, dass mir hier offensichtlich etwas fehlt. Das Entfernen der Schlüsseleinschränkung mit user_email und der Versuch, den Wert in user zu aktualisieren, führt zu demselben Fehler, jedoch für die nächste alphabetische user-untergeordnete Tabelle. Ich glaube nicht, dass es sich um einen tabellenspezifischen Fehler handelt.

BEARBEITEN:

Hinzufügen in den Ergebnissen von 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
15
Paul Mennega

Vor kurzem habe ich unsere MySQL-Datenbank in MySQL Workbench aufgerufen, und als ich die Tabellenbeziehungen für die obigen Tabellen sah, bemerkte ich "Duplikate" und/oder falsche Beziehungen, die ich vorher irgendwie vermisst hatte wird in PHPMyAdmin FWIW nicht angezeigt). Durch das Entfernen dieser zusätzlichen Beziehungen wurde das Problem sofort gelöst.

1
Paul Mennega

Ich löste meine ' Fremdschlüsselbedingung-Fehler ' - Probleme, indem ich den folgenden Code am Anfang des SQL-Codes anfügte (dies war das Importieren von Werten in eine Tabelle)

SET @[email protected]@CHARACTER_SET_CLIENT;
SET @[email protected]@CHARACTER_SET_RESULTS;
SET @[email protected]@COLLATION_CONNECTION;
SET NAMES utf8;
SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @[email protected]@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
SET @[email protected]@SQL_NOTES, SQL_NOTES=0; 

Dann fügen Sie diesen Code am Ende der Datei ein

SET [email protected]_SQL_MODE;
SET [email protected]_FOREIGN_KEY_CHECKS;
SET [email protected]_UNIQUE_CHECKS;
SET [email protected]_CHARACTER_SET_CLIENT;
SET [email protected]_CHARACTER_SET_RESULTS;
SET [email protected]_COLLATION_CONNECTION;
SET [email protected]_SQL_NOTES; 
11
Sidupac

Da Sie keine Tabellendefinitionen angegeben haben, ist es schwer zu erraten. Es sieht jedoch so aus, als würden Sie versuchen, den Fremdschlüssel in der untergeordneten Tabelle zu ändern. AFAIK, das ist illegal, Sie können es vom übergeordneten Element aus ändern, nicht jedoch von der untergeordneten Tabelle.

Betrachten Sie dieses Beispiel:

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

Dann ist das erlaubt:

UPDATE parent
  SET parent_id = 3 WHERE parent_id = 2;

SELECT * FROM parent;
SELECT * FROM child1;
SELECT * FROM child2;

Dies ist jedoch nicht der Fall, da die übergeordnete Datei fk aus der untergeordneten Tabelle geändert wird:

UPDATE child1
  SET fk_parent_id = 4 WHERE fk_parent_id = 1;

Es wird ein Fehler angezeigt, der Ihrem Fehler sehr ähnlich ist:

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):
8
walrii

Ich war mit dem gleichen Problem konfrontiert, als ich auf dem Tisch fremde Einschränkungen aufstellte. Die einfachste Möglichkeit, dieses Problem zu lösen, besteht darin, zunächst eine Sicherung der übergeordneten und untergeordneten Tabelle zu erstellen, dann die untergeordnete Tabelle abzuschneiden und erneut eine Beziehung herzustellen. Ich hoffe, das löst das Problem.

4
Varun

Ein solcher Fehler bei der Aktualisierung kann durch den Unterschied in Zeichensatz und Sortierfolge verursacht werden. Stellen Sie daher sicher, dass sie für beide Tabellen gleich sind.

1
Anna

Obwohl dies ziemlich alt ist, möchte ich nur sagen, dass in @ Sidupacs Antwort der FOREIGN_KEY_CHECKS=0 Nützlich ist.

Diese Antwort ist keine Option, wenn Sie etwas verwenden, das das Datenbankschema für Sie verwaltet (in meinem Fall JPA), aber das Problem kann sein, dass Ihre Tabelle "verwaiste" Einträge enthält (die auf einen Fremdschlüssel verweisen, der möglicherweise nicht vorhanden ist).

Dies kann häufig vorkommen, wenn Sie eine MySQL-Tabelle von MyISAM nach InnoDB konvertieren, da die referenzielle Integrität bei der ersteren nicht wirklich eine Rolle spielt.

1
robin850