When you’re working with Oracle databases, some errors pop up so regularly that DBAs almost recite them in their sleep. ORA-00904: invalid identifier is certainly one of those classic offenders. On the face of it, ORA-00904 indicates you’ve referenced a column or other identifier that Oracle can’t locate or doesn’t consider valid. Straightforward enough—maybe there’s a simple typo, or a missing column in your table. But there are subtler corners of Oracle that can trigger the same error even when you think you’ve done everything right.
Meaning of ORA-00904: Oracle throws ORA-00904 when it encounters an invalid identifier (most often an invalid column name). This usually means: (a) the SQL is referring to a column or alias that does not exist in the specified table(s), or (b) the identifier is not valid according to Oracle’s naming rules. The error message text often includes the problematic identifier in quotes. For example:
ORA-00904: “EMPID”: invalid identifier
This tells us that EMPID is the identifier that Oracle deemed not worthy.
Oracle has strict rules for identifiers (such as column or table names). A valid identifier must meet the following criteria:
Normally, Oracle identifiers are case-insensitive (Oracle stores them in uppercase). For example, a column created as CustomerName or customername is stored as CUSTOMERNAME and can be referenced as customername in SQL. However, if you create an identifier with double quotes, it becomes case-sensitive and must be referenced exactly as created (with matching case and quotes). A common mistake is creating or quoting an identifier and then referencing it without quotes or with wrong case, leading Oracle to treat it as a different name. This mismatch will result in ORA-00904. (In essence, “MyColumn” is a different identifier than MYCOLUMN.)
Version Differences: Aside from the identifier length increase (30 chars to 128 chars) in newer Oracle versions, the fundamental causes of ORA-00904 remain the same across versions. What can differ are the specific reserved words (new Oracle versions may introduce new keywords) and the environment (e.g. some Oracle tools might give slightly more info on the error). Always refer to the Oracle documentation for your version if you suspect a keyword or naming rule issue. The Oracle error message reference confirms the cause is an invalid or missing identifier and reiterates the naming rules for the given version.
Here are some of the most common scenarios of ORA-00904 (schema changes, query issues, or syntax mistakes) that lead to an “invalid identifier” error. If you’ve already:
The most typical cause is referencing a column that does not exist in the table or view. This could be due to a simple typo or because the column was dropped/renamed in the schema. For example, selecting or filtering on a non-existent column triggers ORA-00904. If a table EMP has a column EMPNO and you query SELECT empid FROM emp;, Oracle will throw ORA-00904 for “EMPID”. Similarly, DELETE FROM emp WHERE empid = 123; would error if empid is not a valid column. Such issues often happen after schema changes (a column renamed or removed) or due to mistakes in the SQL.
Any INSERT, UPDATE, or DELETE that mentions a column that doesn’t exist will raise ORA-00904. For instance, UPDATE scott.emp SET salary=1000 WHERE empno=1234; would fail with “SALARY: invalid identifier” if the EMP table’s salary column’s name is SAL or SALARY doesn’t exist. Likewise, an INSERT that lists a non-existent column will trigger the error. In many cases, these errors are due to typos or using the wrong column names (perhaps mixing up logical names vs. actual database names).
As mentioned, if you use an Oracle reserved keyword for a column or table name without quoting it, Oracle will flag it as an invalid identifier. This commonly occurs when porting SQL from other databases or by accident. For example, attempting to create a table with a column named COMMENT or AUDIT will result in ORA-00904. In one case, defining a column AUDIT VARCHAR2(1000) caused Oracle to throw ORA-00904 at that line. Oracle’s error text might not explicitly say “reserved word,” but it points to the problematic identifier. (Commonly misused keywords include COMMENT, CHECK, LEVEL, PRIOR, RESOURCE, etc.)
If someone created a table or column with double quotes (making it case-sensitive or containing special characters), any SQL referencing it must use the exact same casing and quotes. Forgetting to do so leads to ORA-00904. For example, if a table creation involved CREATE TABLE bad_design(“MixedCaseColumn” NUMBER);, then SELECT MixedCaseColumn FROM bad_design; will error – it must be SELECT “MixedCaseColumn” FROM bad_design;
Best practice is to avoid using quoted identifiers unless necessary, to steer clear of this pitfall.
An alias defined in a SELECT clause cannot be reused in the same SELECT’s WHERE or GROUP BY clause in Oracle (because of SQL parsing order). If you attempt to do so, Oracle will not recognize the alias and will throw ORA-00904 for that alias name. For example: SELECT (col1+col2) AS total FROM my_table WHERE total > 100; will result in “TOTAL: invalid identifier” because total is not known in the WHERE clause at parse time. The solution is to repeat the expression or use a subquery/VIEW. Additionally, if you alias a column with a quoted name, you must use the exact quoted alias in ORDER BY or other references. The following demonstrates a subtle alias issue:
SELECT column_name AS “column_id”
FROM my_table
ORDER BY column_id; — Oracle throws ORA-00904 here
When using a USING(column) clause in a JOIN, that column name becomes a shared identifier and its reference should be without a table qualifier. If you mistakenly qualify it with a table alias, Oracle will throw an invalid identifier error. For example:
SELECT a.id, b.data
FROM tableA a JOIN tableB b USING(id);
Here you should select id (not a.id or b.id) after a USING join. Qualifying a.id or b.id in the select or where clause would be invalid in this context.
Sometimes ORA-00904 is a side-effect of a syntax error that causes Oracle to interpret something as an identifier. A classic case is a trailing comma in a column list. For instance, CREATE TABLE Test (ID NUMBER, NAME VARCHAR2(50), ); has an extra comma, so Oracle expects another column name after it. This results in ORA-00904 (essentially complaining about a missing identifier after the comma). Similarly, if you accidentally miss a quote around a string literal in a WHERE clause (e.g. WHERE name = John instead of name = ‘John’), Oracle will read John as an identifier and likely throw ORA-00904 for that token. Other typos like using square brackets (common in SQL Server) around names will also cause Oracle to treat them as invalid characters/identifiers.
Less commonly, ORA-00904 can appear if the table or column isn’t accessible to the user. For example, if you reference another schema’s table without proper rights or without prefixing the schema, Oracle might say the column is invalid (since it can’t find the table or column). Typically, missing permissions yield ORA-00942 (table/view does not exist), but if a synonym or view hides the table, a missing column could surface as ORA-00904. Ensuring reference to the correct schema and that the user has SELECT privileges can resolve this.
Encountering ORA-00904 can be frustrating, but a systematic check can pinpoint the cause. Use the following steps to troubleshoot and fix the error:
Note the exact identifier reported in the error (it will be in the quotes in the ORA-00904 message). This is the name Oracle couldn’t recognize. For example, an error might point to “DEPT_ID” or EMPID. This is your starting clue.
Check if that column or identifier actually exists in the referenced table or context.
If the identifier doesn’t appear to be a simple typo, evaluate it against Oracle’s naming rules:
If the error refers to an alias (maybe one you defined in the SELECT list), remember that you generally cannot use that alias in the WHERE, GROUP BY, or HAVING of the same query. Oracle will not substitute the alias at parse time, leading to ORA-00904. For example, an alias in the SELECT can be used in the ORDER BY (since that is handled after selection), but not in the WHERE. The solution is to restructure the query. You can either repeat the expression or use a subquery/with-clause to define the alias and then refer to it outside. Also, if you see an alias with quotes in the error, ensure that you’re referencing it with the exact same quotes and casing wherever needed (especially in ORDER BY).
If everything seems correct with the names, inspect the SQL for any syntax issues:
Make sure you’re executing the query on the correct schema and with an account that has access. If the error arises from a missing reference due to schema qualification, prefix the table with the schema name or create a synonym. If it’s due to permissions (e.g., selecting from a table you don’t have rights to), consider that the error could be Oracle indicating it can’t find the column. Grant appropriate privileges or run as a user that owns the table. (While a permissions issue typically raises ORA-00942, double-check this aspect if all else looks correct.)
Following these steps will usually identify the root cause of ORA-00904. Once you spot the issue (be it a typo, a missing column, a reserved word, etc.), apply the appropriate fix: correct the spelling, modify the schema, quote the identifier, or adjust the query logic. Always test the corrected query to ensure the error is resolved.
By following these practices, you can minimize the chances of hitting ORA-00904 and ensure smoother SQL execution.