Le type des colonnes diffère : #1215 - Cannot add foreign key constraint

Si le type de 2 colonnes à mettre en relation, vous ne pouvez pas poser votre FK. Dans l'exemple suivant, les types sont presque identique, sauf le signé et unsigned :

ALTER TABLE `vente` ADD CONSTRAINT `vente_ibfk_fournisseur` FOREIGN KEY ( `idfournisseur` ) REFERENCES `fournisseur` (`idFournisseur`) ON DELETE RESTRICT ON UPDATE CASCADE ;
-- #1215 - Cannot add foreign key constraint 

DESCRIBE vente;
+-------------------------------------+----------------------+------+-----+---------+----------------+
| Field                               | Type                 | Null | Key | Default | Extra          |
+-------------------------------------+----------------------+------+-----+---------+----------------+
| idVente                             | int(11)              | NO   | PRI | NULL    | auto_increment |
| idfournisseur                       | smallint(11)         | YES  | MUL | NULL    |                |

DESCRIBE fournisseur;
+------------------------------------+----------------------+------+-----+---------+----------------+
| Field                              | Type                 | Null | Key | Default | Extra          |
+------------------------------------+----------------------+------+-----+---------+----------------+
| idFournisseur                      | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment |

SELECT * 
FROM vente
LEFT JOIN fournisseur ON fournisseur.idFournisseur  = vente.idFournisseur
WHERE fournisseur.idFournisseur IS NULL
AND vente.idFournisseur IS NOT NULL;
-- aucun résultat, pas de "trou" sans relation entres les 2 tables

ALTER TABLE `vente` CHANGE `idfournisseur` `idfournisseur` SMALLINT UNSIGNED NULL DEFAULT NULL ;

DESCRIBE vente;
+-------------------------------------+----------------------+------+-----+---------+----------------+
| Field                               | Type                 | Null | Key | Default | Extra          |
+-------------------------------------+----------------------+------+-----+---------+----------------+
| idVente                             | int(11)              | NO   | PRI | NULL    | auto_increment |
| idfournisseur                       | smallint(5) unsigned | YES  | MUL | NULL    |                |

ALTER TABLE `vente` ADD CONSTRAINT `vente_ibfk_fournisseur` FOREIGN KEY ( `idfournisseur` ) REFERENCES `fournisseur` (`idFournisseur`) ON DELETE RESTRICT ON UPDATE CASCADE ;
-- OK

Il manque des données dans la table mère : #1452 - Cannot add or update a child row: a foreign key constraint fails

Il y a des trous à boucher, des lignes de factures ne sont associées à aucune vente

-- #1452 - Cannot add or update a child row: a foreign key constraint fails (`#sql-49d_13194e`, CONSTRAINT `vente_ibfk_factureligne` FOREIGN KEY (`idfactureligne`) REFERENCES `factureligne` (`idFactureLigne`)) 
SELECT * 
FROM vente AS t1
LEFT JOIN factureligne AS t2 ON t2.idFactureLigne  = t1.idFactureLigne
WHERE t2.idFactureLigne IS NULL
AND t1.idFactureLigne IS NOT NULL;
-- Il y a des résultats, alors qu'aucun résultat n'est attendu !

Gestion des erreurs avec MySQL

Sur mysql/error-handling

  • Erreur: 1215 SQLSTATE: HY000 (ER_CANNOT_ADD_FOREIGN) : Message: Impossible d'ajouter des contraintes d'index externe
  • Erreur: 1452 SQLSTATE: 23000 (ER_NO_REFERENCED_ROW_2) : Message: Cannot add or update a child row: a foreign key constraint fails (%s)