Errore Mysql 1452 – Imansible aggiungere o aggiornare una riga secondaria: un vincolo di chiave esterna non riesce

Sto avendo un po ‘di strano problema. Sto cercando di aggiungere una chiave esterna a una tabella che fa riferimento a un’altra, ma non funziona per qualche motivo. Con la mia conoscenza limitata di MySQL, l’unica cosa che potrebbe essere sospetta è che c’è una chiave straniera su una tabella diversa che fa riferimento a quella che sto cercando di fare riferimento.

Ecco una foto delle mie relazioni con la tabella, generate tramite phpMyAdmin: Relationships

Ho fatto una query SHOW CREATE TABLE su entrambe le tabelle, sourcecodes_tags è la tabella con la chiave esterna, i sourcecodes è la tabella di riferimento.

 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 

Sarebbe bello se qualcuno potesse dirmi cosa sta succedendo qui, non ho avuto alcuna formazione formale o nulla con MySQL 🙂

Grazie.

    Modifica: questo è il codice che genera l’errore:

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

    Molto probabilmente la tabella sourcecodes_tags contiene valori sourcecode_id che non esistono più nella tabella dei sourcecodes . Devi liberarti di quelli prima.

    Ecco una query che può trovare quegli ID:

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

    Ho avuto lo stesso problema con il mio database MySQL ma alla fine ho trovato una soluzione che ha funzionato per me.
    Dato che nella mia tabella tutto andava bene dal punto di vista mysql (entrambe le tabelle dovrebbero utilizzare il motore Innodb e il tipo di dati di ogni colonna dovrebbe essere dello stesso tipo che prende parte al vincolo di chiave esterna).
    L’unica cosa che ho fatto è stata disabilitare il controllo della chiave esterna e in seguito abilitato dopo aver eseguito un’operazione con chiave esterna.
    Passi che ho preso:

     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; 

    Usa NOT IN per trovare dove vincoli sono vincolanti :

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

    quindi, più precisamente:

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

    EDIT: gli operatori IN e NOT IN sono molto più veloci degli operatori JOIN , oltre che molto più facili da build e ripetere.

    Troncare le tabelle e quindi provare ad aggiungere il vincolo FK .

    So che questa soluzione è un po ‘imbarazzante ma funziona al 100%. Ma sono d’accordo che questa non è una soluzione ideale per affrontare il problema, ma spero che aiuti.

    Questo accade anche quando si imposta una chiave esterna su parent.id su child.column se child.column ha già un valore di 0 e nessun valore parent.id è 0

    Dovresti assicurarti che ogni child.column sia NULL o abbia un valore che esiste in parent.id

    E ora che ho letto la dichiarazione nos ha scritto, questo è ciò che sta convalidando.

    Per me, questo problema era un po ‘diverso e super facile da controllare e risolvere.

    È necessario assicurarsi che ENTRAMBI i tuoi tavoli siano InnoDB. Se una delle tabelle, ovvero la tabella di riferimento è un MyISAM, il vincolo fallirà.

     SHOW TABLE STATUS WHERE Name = 't1'; ALTER TABLE t1 ENGINE=InnoDB; 

    Ho avuto lo stesso problema oggi. Ho provato per quattro cose, alcune delle quali già menzionate qui:

    1. Ci sono dei valori nella colonna figlio che non esistono nella colonna genitore (oltre a NULL, se la colonna figlio è annullabile)

    2. Le colonne figlio e genitore hanno lo stesso tipo di dati?

    3. C’è un indice sulla colonna genitore a cui fai riferimento? MySQL sembra richiedere questo per motivi di prestazioni ( http://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html )

    4. E questo l’ha risolto per me: entrambi i tavoli hanno identiche regole di confronto?

    Avevo un tavolo in utf-8 e l’altro in iso-qualcosa. Questo non ha funzionato. Dopo aver modificato il confronto tra iso-tabella e utf-8, è ansible aggiungere i vincoli senza problemi. Nel mio caso, phpMyAdmin non ha nemmeno mostrato la tabella figlio in codifica iso nel menu a discesa per la creazione del vincolo di chiave esterna.

    Sembra che ci sia un valore non valido per la colonna come 0 che non è una chiave esterna valida, quindi MySQL non può impostare un vincolo di chiave esterna per questo.

    È ansible seguire questi passaggi:

    1. Rilasciare la colonna per cui si è tentato di impostare il vincolo FK.

    2. Aggiungilo nuovamente e imposta il suo valore predefinito come NULL.

    3. Prova a impostare di nuovo il vincolo di chiave esterna.

    Avrei avuto lo stesso problema, ho controllato le righe dei miei tavoli e ho scoperto che c’erano alcune incompatibilità con il valore dei campi che volevo definire come chiave esterna. Ho corretto questi valori, ho provato di nuovo e il problema è stato risolto.

    Finisco per eliminare tutti i dati nella mia tabella, ed eseguo nuovamente l’alterazione. Funziona. Non brillante, ma risparmia molto tempo, specialmente la tua applicazione è ancora in fase di sviluppo senza dati del cliente.

    prova questo

     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; 

    Ho avuto questo stesso identico problema in tre diverse occasioni. In ogni caso era perché uno (o più) dei miei record non era conforms alla nuova chiave esterna. Potresti voler aggiornare i tuoi record esistenti per seguire i vincoli di syntax della chiave esterna prima di provare ad aggiungere la chiave stessa. L’esempio seguente dovrebbe generalmente isolare i record del problema:

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

    ripeti AND (candidate key) <> (next proposed foreign key value) all’interno della query per ogni valore nella chiave esterna.

    Se hai un sacco di dischi questo può essere difficile, ma se il tuo tavolo è ragionevolmente piccolo non dovrebbe richiedere troppo tempo. Non sono eccezionale nella syntax SQL, ma questo ha sempre risolto il problema per me.

    Svuota i dati di entrambe le tabelle ed esegui il comando. Funzionerà.

    Stavo ricevendo questo errore durante l’uso di Laravel ed eloquente, il tentativo di creare un collegamento di chiave esterna avrebbe causato un errore 1452. Il problema era la mancanza di dati nella tabella collegata.

    Vedi qui per un esempio: http://mstd.eu/index.php/2016/12/02/laravel-eloquent-integrity-constraint-violation-1452-foreign-key-constraint/

    Ho una soluzione, devi solo rispondere a una domanda:

    La tua tabella sta già memorizzando i dati? Soprattutto il tavolo includeva chiave esterna.

    Se la risposta è sì, allora l’unica cosa che fai è cancellare tutto il record e quindi sei libero di aggiungere qualsiasi chiave esterna nella tua tabella.

    Elimina istruzione: dal figlio (che include la tabella di chiavi esterne) alla tabella padre.

    Il motivo per cui non è ansible aggiungere la chiave esterna dopo le voci di dati è dovuto all’incoerenza della tabella, che cosa si intende gestire con la nuova chiave esterna nella precedente tabella di dati riempita?

    Se no, quindi seguire le altre istruzioni.

    Stavo preparando queste soluzioni e questo esempio può essere d’aiuto.

    Il mio database ha due tabelle (email e credit_card) con chiavi primarie per i loro ID. Un’altra tabella (client) fa riferimento a questi ID tabelle come chiavi esterne. Ho un motivo per escludere l’e-mail dai dati del cliente.

    Innanzitutto inserisco i dati delle righe per le tabelle di riferimento (email, credit_card), quindi ottieni l’ID per ciascuno, quegli ID sono necessari nella terza tabella (client).

    Se non si inseriscono prima le righe nelle tabelle di riferimento, MySQL non sarà in grado di effettuare le corrispondenze quando si inserisce una nuova riga nella terza tabella che fa riferimento alle chiavi esterne.

    Se prima si inseriscono le righe di riferimento per le tabelle di riferimento, quindi la riga che fa riferimento a chiavi esterne, non si verifica alcun errore.

    Spero che questo ti aiuti.

    Assicurati che il valore sia nell’altra tabella altrimenti otterrai questo errore, nella colonna corrispondente assegnata.

    Quindi se la colonna assegnata è assegnata all’id della riga di un’altra tabella, assicurati che ci sia una riga nella tabella altrimenti questo errore apparirà.

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

    dovrebbe aiutare a sbarazzarsi di quegli ID. O se null non è consentito in sourcecode_id , quindi rimuovere quelle righe o aggiungere quei valori mancanti alla tabella sourcecodes .

    Ho avuto lo stesso problema e ho trovato la soluzione, posizionando NULL invece di NOT NULL sulla colonna chiave esterna. Ecco una query:

     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 ha eseguito questa query!