
L’erreur ORA-00904 « invalid identifier » signifie qu’Oracle ne reconnaît pas un nom de colonne utilisé dans votre requête : soit la colonne n’existe pas (faute de frappe, mauvaise table), soit son nom doit être écrit entre guillemets doubles parce qu’il a été créé ainsi. Voici comment l’identifier et la corriger en quelques minutes.
Que signifie exactement ORA-00904 ?
Le message complet ressemble à ceci :
ORA-00904: "NOM_CLIENT" : identificateur non valide
ORA-00904: "NOM_CLIENT": invalid identifierOracle vous dit : « tu fais référence à une colonne NOM_CLIENT, mais je ne la trouve pas dans les tables de ta requête ». Contrairement à ORA-00942 (table introuvable), ORA-00904 concerne toujours une colonne.
Les 5 causes les plus fréquentes (et leurs solutions)
1. Faute de frappe dans le nom de colonne
La cause n°1, de loin. Vérifiez l’orthographe exacte avec DESC :
DESC clients;
-- ou
SELECT column_name FROM user_tab_columns WHERE table_name = 'CLIENTS';2. La colonne existe… dans une autre table
Dans une jointure, le préfixe est peut-être faux :
-- ❌ ORA-00904 : "c.date_commande" n'existe pas dans CLIENTS
SELECT c.nom, c.date_commande
FROM clients c JOIN commandes cmd ON cmd.client_id = c.id;
-- ✅ la colonne appartient à COMMANDES
SELECT c.nom, cmd.date_commande
FROM clients c JOIN commandes cmd ON cmd.client_id = c.id;3. Colonne créée entre guillemets doubles
Si la table a été créée avec CREATE TABLE t ("MaColonne" NUMBER), Oracle a stocké le nom en respectant la casse. Il faut alors l’écrire à l’identique, entre guillemets :
SELECT "MaColonne" FROM t; -- ✅
SELECT MaColonne FROM t; -- ❌ ORA-00904Conseil : évitez les guillemets doubles à la création des tables, ils causent ce piège en permanence.
4. Alias utilisé au mauvais endroit
Un alias de colonne défini dans le SELECT n’est pas utilisable dans le WHERE (il n’existe pas encore à ce stade d’exécution) :
-- ❌ ORA-00904 : "TOTAL_TTC" inconnu dans WHERE
SELECT prix_ht * 1.20 AS total_ttc FROM ventes WHERE total_ttc > 100;
-- ✅ répéter l'expression, ou passer par une sous-requête
SELECT prix_ht * 1.20 AS total_ttc FROM ventes WHERE prix_ht * 1.20 > 100;
SELECT * FROM (SELECT prix_ht * 1.20 AS total_ttc FROM ventes) WHERE total_ttc > 100;L’alias est en revanche autorisé dans ORDER BY. Pour approfondir : notre tutoriel sur la clause WHERE.
5. Mot réservé ou colonne ajoutée récemment
Vous utilisez un mot réservé d’Oracle comme nom de colonne (NUMBER, DATE, SIZE…), ou la colonne vient d’être ajoutée sur un autre environnement (DEV mais pas PROD). Vérifiez l’environnement et comparez :
SELECT table_name, column_name
FROM all_tab_columns
WHERE column_name = 'STATUT' AND owner = 'MONSCHEMA';ORA-00904 dans un INSERT, UPDATE ou CREATE
L’erreur survient aussi hors SELECT :
- INSERT : une colonne de la liste n’existe pas —
INSERT INTO clients (nom, telephonne) VALUES (...)→ vérifiez avecDESC clients. Voir notre guide INSERT en SQL Oracle. - UPDATE : même principe sur le
SET. Voir UPDATE en SQL Oracle. - CREATE TABLE : un type mal écrit peut être interprété comme un identifiant —
CREATE TABLE t (id NUMBR)déclenche ORA-00904.
Checklist de résolution rapide
DESC ma_table→ la colonne existe-t-elle, avec cette orthographe exacte ?- Dans une jointure : le préfixe (
alias.colonne) pointe-t-il vers la bonne table ? - Le nom a-t-il été créé entre guillemets doubles ? → reproduire la casse exacte entre
"…". - Utilisez-vous un alias dans le
WHERE? → répétez l’expression ou sous-requête. - Êtes-vous sur le bon schéma / environnement ? →
all_tab_columns.
FAQ
ORA-00904 peut-elle venir d’une table inexistante ?
Non : une table introuvable déclenche ORA-00942. ORA-00904 concerne uniquement les colonnes (ou identifiants assimilés).
Pourquoi ma requête marche en DEV mais pas en PROD ?
La colonne existe probablement en DEV mais pas encore en PROD (migration non appliquée). Comparez les deux schémas avec all_tab_columns.
Les noms de colonnes Oracle sont-ils sensibles à la casse ?
Par défaut non — Oracle stocke tout en MAJUSCULES. Ils le deviennent uniquement si la colonne a été créée entre guillemets doubles.
