
ORA-02291 « integrity constraint violated – parent key not found » signifie que vous insérez (ou modifiez) une ligne dont la clé étrangère pointe vers un parent qui n’existe pas. Exemple type : une commande pour un client_id absent de la table clients. Voici comment identifier la relation en cause et les bonnes solutions.
Le message
ORA-02291: integrity constraint (MONSCHEMA.FK_CMD_CLIENT) violated - parent key not found
ORA-02291: violation de contrainte d'intégrité - clé parent introuvableOracle nomme la contrainte (FK_CMD_CLIENT) : c’est une clé étrangère. La valeur que vous insérez dans la colonne enfant n’a pas de correspondance dans la table parent.
Étape 1 — Identifier la relation (enfant → parent)
SELECT a.table_name AS table_enfant,
a.column_name AS colonne_fk,
c_pk.table_name AS table_parent,
pk.column_name AS colonne_parent
FROM user_constraints c
JOIN user_cons_columns a ON a.constraint_name = c.constraint_name
JOIN user_constraints c_pk ON c_pk.constraint_name = c.r_constraint_name
JOIN user_cons_columns pk ON pk.constraint_name = c_pk.constraint_name
WHERE c.constraint_name = 'FK_CMD_CLIENT';Vous savez maintenant : commandes.client_id doit exister dans clients.id. (Rappel : notre guide des contraintes Oracle.)
Étape 2 — Vérifier que le parent existe
-- la valeur insérée existe-t-elle côté parent ?
SELECT * FROM clients WHERE id = 4242;
-- (aucune ligne → c'est la cause)Étape 3 — Choisir la solution adaptée
Solution 1 : créer le parent d’abord (ordre d’insertion)
Dans une relation, on insère toujours le parent avant l’enfant :
INSERT INTO clients (id, nom) VALUES (4242, 'Durand'); -- parent d'abord
INSERT INTO commandes (id, client_id, total) VALUES (1, 4242, 99); -- puis enfantSolution 2 : corriger la valeur de la clé étrangère
Souvent, le client_id est simplement faux (mauvais ID, valeur d’un autre environnement). Reliez la commande au bon client existant.
Solution 3 : autoriser l’absence de parent → clé étrangère NULL
Si « pas de parent » est un cas métier valide (commande sans client attribué), la colonne enfant peut être NULL : une FK n’est pas vérifiée quand la valeur est NULL.
INSERT INTO commandes (id, client_id, total) VALUES (1, NULL, 99); -- ✅ accepté
-- (à condition que la colonne client_id soit nullable)Le piège de l’ordre lors d’un chargement de masse
En insérant des milliers de lignes via plusieurs tables, l’ordre casse facilement. Deux options :
- Charger dans le bon ordre (toutes les tables parents, puis les enfants).
- Différer la vérification avec une contrainte
DEFERRABLE, validée seulement au COMMIT :
-- à la création de la contrainte
ALTER TABLE commandes ADD CONSTRAINT fk_cmd_client
FOREIGN KEY (client_id) REFERENCES clients(id) DEFERRABLE INITIALLY DEFERRED;
-- dans la transaction
INSERT INTO commandes ...; -- ordre quelconque
INSERT INTO clients ...;
COMMIT; -- la cohérence est vérifiée iciCas particulier — ORA-02291 sur un UPDATE
Modifier client_id vers une valeur inexistante déclenche la même erreur. Vérifiez la valeur cible avant l’UPDATE (voir UPDATE en SQL Oracle).
FAQ
Quelle différence avec ORA-02292 ?
ORA-02291 : l’enfant référence un parent absent (à l’INSERT/UPDATE de l’enfant). ORA-02292 : on tente de supprimer un parent encore référencé par des enfants (« child record found »).
Comment trouver toutes les clés étrangères d’une table ?
SELECT constraint_name, r_constraint_name FROM user_constraints WHERE table_name='COMMANDES' AND constraint_type='R';
Mettre la FK en NULL est-il une bonne idée ?
Seulement si « sans parent » a un sens métier. Sinon, corrigez la donnée : neutraliser la contrainte masquerait une incohérence réelle.
