wake-up-neo.com

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

Ich habe ein seltsames Problem. Ich versuche, einer Tabelle einen Fremdschlüssel hinzuzufügen, der auf eine andere verweist, der jedoch aus irgendeinem Grund fehlschlägt. Mit meinen begrenzten Kenntnissen in MySQL könnte man nur vermuten, dass sich in einer anderen Tabelle ein Fremdschlüssel befindet, der auf den zu referenzierenden verweist.

Hier ist ein Bild meiner über phpMyAdmin erzeugten Tabellenbeziehungen: Relationships

Ich habe eine SHOW CREATE TABLE-Abfrage für beide Tabellen durchgeführt. sourcecodes_tags ist die Tabelle mit dem Fremdschlüssel, sourcecodes ist die referenzierte Tabelle.

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

Es wäre toll, wenn mir jemand sagen könnte, was hier los ist. Ich habe keine Schulung oder etwas mit MySQL gemacht :)

Vielen Dank.

Edit: Dies ist der Code, der den Fehler generiert:

ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE
227
Zim

Wahrscheinlich enthält Ihre sourcecodes_tags-Tabelle sourcecode_id-Werte, die in Ihrer sourcecodes-Tabelle nicht mehr vorhanden sind. Sie müssen diese zuerst loswerden.

Hier ist eine Abfrage, die diese IDs finden kann:

SELECT DISTINCT sourcecode_id FROM 
   sourcecodes_tags tags LEFT JOIN sourcecodes sc ON tags.sourcecode_id=sc.id 
WHERE sc.id IS NULL;
220
nos

Ich hatte das gleiche Problem mit meiner MySQL-Datenbank, aber schließlich bekam ich eine Lösung, die für mich funktionierte.
Da in meiner Tabelle aus Sicht der MySQL-Ansicht alles in Ordnung war (beide Tabellen sollten die Innodb-Engine verwenden und der Datentyp jeder Spalte sollte vom gleichen Typ sein, der an der Fremdschlüsseleinschränkung beteiligt ist).
Das einzige, was ich tat, war, die Fremdschlüsselprüfung zu deaktivieren und sie später nach dem Fremdschlüsselvorgang zu aktivieren.
Schritte, die ich unternommen habe:

mysql> SET foreign_key_checks = 0;

mysql> alter table tblUsedDestination add constraint f_operatorId foreign key(iOperatorId) references tblOperators (iOperatorId); Query
OK, 8 rows affected (0.23 sec) Records: 8  Duplicates: 0  Warnings: 0

mysql> SET foreign_key_checks = 1;
91
Prakash

Verwenden Sie NOT IN, um herauszufinden, wo die Einschränkungen sindconstraining:

SELECT column FROM table WHERE column NOT IN 
(SELECT intended_foreign_key FROM another_table)

also genauer:

SELECT sourcecode_id FROM sourcecodes_tags WHERE sourcecode_id NOT IN 
(SELECT id FROM sourcecodes)

BEARBEITEN: IN- und NOT IN-Operatoren sind dafür bekannt, dass sie viel schneller als die JOIN-Operatoren sind.

55
Ryan Ward

Schneiden Sie die Tabellen ab und fügen Sie dann die FK-Einschränkung hinzu.

Ich weiß, dass diese Lösung etwas umständlich ist, aber sie funktioniert zu 100%. Ich stimme jedoch zu, dass dies keine ideale Lösung für das Problem ist, aber ich hoffe, es hilft.

23

Für mich war dieses Problem etwas anders und sehr einfach zu überprüfen und zu lösen. 

Sie müssen sicherstellen, dass BEIDE für Ihre Tabellen InnoDB sind. Wenn eine der Tabellen, nämlich die Referenztabelle, MyISAM ist, schlägt die Einschränkung fehl.

SHOW TABLE STATUS WHERE Name =  't1';

ALTER TABLE t1 ENGINE=InnoDB;
15
zmonteca

Ich hatte heute das gleiche Problem. Ich habe vier Dinge getestet, von denen einige hier bereits erwähnt wurden:

  1. Gibt es Werte in Ihrer untergeordneten Spalte, die in der übergeordneten Spalte nicht vorhanden sind (außer NULL, wenn die untergeordnete Spalte nullfähig ist)

  2. Haben untergeordnete und übergeordnete Spalten den gleichen Datentyp?

  3. Gibt es einen Index für die übergeordnete Spalte, auf die Sie verweisen? MySQL scheint dies aus Leistungsgründen zu erfordern ( http://dev.mysql.com/doc/refman/5.5/de/create-table-foreign-keys.html )

  4. Und das hat es für mich gelöst: Haben beide Tabellen identische Sortierungen? 

Ich hatte einen Tisch in Utf-8 und den anderen in Iso-Etwas. Das hat nicht funktioniert. Nachdem die Iso-Tabelle in utf-8-Sortierung geändert wurde, konnten die Einschränkungen problemlos hinzugefügt werden. In meinem Fall hat phpMyAdmin in der Dropdown-Liste die untergeordnete Tabelle nicht einmal in Isocodierung angezeigt, um die Fremdschlüsseleinschränkung zu erstellen.

14
Michael Helwig

Dies geschieht auch beim Festlegen eines Fremdschlüssels auf parent.id auf child.column, wenn die child.column bereits einen Wert von 0 hat und kein parent.id-Wert 0 ist

Sie müssen sicherstellen, dass jede child.column NULL ist oder einen Wert hat, der in parent.id vorhanden ist

Und jetzt, wo ich die Aussage gelesen habe, die nos geschrieben hat, bestätigt er dies.

14
fyrye

Anscheinend gibt es für die Spalte einen ungültigen Wert wie 0, der kein gültiger Fremdschlüssel ist. MySQL kann daher keine Fremdschlüsseleinschränkung festlegen.

Sie können diesen Schritten folgen:

  1. Lassen Sie die Spalte fallen, für die Sie die FK-Einschränkung festgelegt haben.

  2. Fügen Sie es erneut hinzu und setzen Sie seinen Standardwert auf NULL.

  3. Versuchen Sie, die Fremdschlüsseleinschränkung erneut festzulegen.

7
Milad

Ich hätte das gleiche Problem. Ich überprüfte die Zeilen meiner Tabellen und stellte fest, dass die Werte der Felder, die ich als Fremdschlüssel definieren wollte, nicht kompatibel waren. Ich korrigierte diesen Wert, versuchte es erneut und das Problem wurde gelöst.

5
Mostafa -T

versuche dies

SET foreign_key_checks = 0;

ALTER TABLE sourcecodes_tags ADD FOREIGN KEY (sourcecode_id) REFERENCES sourcecodes (id) ON DELETE CASCADE ON UPDATE CASCADE

SET foreign_key_checks = 1;
4
Carlo Guevarra

Am Ende lösche ich alle Daten in meiner Tabelle und führe alter erneut aus. Es klappt. Nicht das Geniale, aber es spart viel Zeit, insbesondere befindet sich Ihre Anwendung noch in der Entwicklungsphase ohne Kundendaten.

4
VHanded

Ich hatte das gleiche Problem ungefähr drei Mal. In jedem Fall lag es daran, dass eine (oder mehrere) meiner Datensätze nicht mit dem neuen Fremdschlüssel übereinstimmten. Sie können Ihre vorhandenen Datensätze aktualisieren, um den Syntaxeinschränkungen des Fremdschlüssels zu folgen, bevor Sie versuchen, den Schlüssel selbst hinzuzufügen. Das folgende Beispiel sollte im Allgemeinen die Problemdatensätze isolieren:

SELECT * FROM (tablename)
    WHERE (candidate key) <> (proposed foreign key value) 
        AND (candidate key) <> (next proposed foreign key value)

wiederholen Sie AND (candidate key) <> (next proposed foreign key value) in Ihrer Abfrage für jeden Wert im Fremdschlüssel.

Wenn Sie eine Menge Platten haben, kann dies schwierig sein, aber wenn Ihr Tisch recht klein ist, sollte er nicht zu lange dauern. Ich bin in der SQL-Syntax nicht besonders verblüffend, aber dies hat das Problem für mich immer isoliert.

2
mopsyd

Ich habe diesen Fehler bei der Verwendung von Laravel und Eloquent erhalten. Der Versuch, eine Fremdschlüsselverknüpfung herzustellen, würde eine 1452 verursachen. Das Problem war das Fehlen von Daten in der verknüpften Tabelle.

Ein Beispiel finden Sie hier: http://mstd.eu/index.php/2016/12/02/laravel-eloquent-integrity-constraint-violation-1452-foreign-key-constraint/

2
twigg

Leeren Sie die Daten Ihrer Tabellen und führen Sie den Befehl aus. Es wird klappen.

2
vijayrana

Ich habe diese Lösungen vorbereitet und dieses Beispiel kann helfen.

Meine Datenbank hat zwei Tabellen (email und credit_card) mit Primärschlüsseln für ihre IDs. Eine andere Tabelle (Client) verweist auf diese Tabellen-IDs als Fremdschlüssel. Ich habe einen Grund, die E-Mail von den Kundendaten zu trennen.

Zuerst füge ich die Zeilendaten für die referenzierten Tabellen ein (E-Mail, credit_card), dann bekomme ich die ID für jede. Diese IDs werden in der dritten Tabelle (Client) benötigt. 

Wenn Sie die Zeilen nicht zuerst in die referenzierten Tabellen einfügen, kann MySQL die Entsprechungen nicht vornehmen, wenn Sie eine neue Zeile in die dritte Tabelle einfügen, die auf die Fremdschlüssel verweist.

Wenn Sie zuerst die referenzierten Zeilen für die referenzierten Tabellen einfügen, tritt in der Zeile, die auf Fremdschlüssel verweist, kein Fehler auf.

Hoffe das hilft.

1

sie können dieses Beispiel ausprobieren

 START TRANSACTION;
 SET foreign_key_checks = 0;
 ALTER TABLE `job_definers` ADD CONSTRAINT `job_cities_foreign` FOREIGN KEY 
 (`job_cities`) REFERENCES `drop_down_lists`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
 SET foreign_key_checks = 1;
 COMMIT;

Hinweis: Wenn Sie phpmyadmin verwenden, deaktivieren Sie das Kontrollkästchen Fremdschlüsselprüfungen aktivieren .

als Beispiel enter image description here

hoffe diese lösung behebt dein problem :)

1
Fouad Mekkey

Stellen Sie sicher, dass sich der Wert in der anderen Tabelle befindet. Andernfalls wird dieser Fehler in der zugeordneten Spalte angezeigt.

Wenn die Spalte einer Zeilen-ID einer anderen Tabelle zugewiesen ist, müssen Sie sicherstellen, dass sich eine Zeile in der Tabelle befindet.

1

Ich habe eine Lösung, Sie müssen nur eine Frage beantworten:

Speichert Ihre Tabelle bereits Daten? Besonders die Tabelle enthielt einen Fremdschlüssel.

Wenn die Antwort "Ja" lautet, müssen Sie nur den gesamten Datensatz löschen. Anschließend können Sie jeden Fremdschlüssel in Ihrer Tabelle hinzufügen.

Löschanweisung: Von untergeordneter (einschließlich Fremdschlüsseltabelle) zur übergeordneten Tabelle.

Der Grund, warum Sie nach der Dateneingabe keinen Fremdschlüssel hinzufügen können, liegt in der Inkonsistenz der Tabelle. Wie gehen Sie mit dem neuen Fremdschlüssel in einer früheren Tabelle mit Datenfüllung um?

Wenn nein, folgen Sie den Anweisungen anderer.

1
nobody
UPDATE sourcecodes_tags
SET sourcecode_id = NULL
WHERE sourcecode_id NOT IN (
  SELECT id FROM sourcecodes);

sollte helfen, diese IDs loszuwerden. Wenn null in sourcecode_id nicht zulässig ist, entfernen Sie diese Zeilen oder fügen Sie diese fehlenden Werte der sourcecodes-Tabelle hinzu.

0
naXa

Ich hatte das gleiche Problem und fand eine Lösung, die NULL anstelle von NOT NULL in der Fremdschlüsselspalte platzierte. Hier ist eine Abfrage:

ALTER TABLE `db`.`table1`
ADD COLUMN `col_table2_fk` INT UNSIGNED NULL,
ADD INDEX `col_table2_fk_idx` (`col_table2_fk` ASC),
ADD CONSTRAINT `col_table2_fk1`
FOREIGN KEY (`col_table2_fk`)
REFERENCES `db`.`table2` (`table2_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;

MySQL hat diese Abfrage ausgeführt!

0
akelec