ORA-01747: Invalid Column Specification - Fix SQL Errors
ORA-01747: Invalid user.table.column Specification
Section titled “ORA-01747: Invalid user.table.column Specification”Error Overview
Section titled “Error Overview”Error Text: ORA-01747: invalid user.table.column, table.column, or column specification
The ORA-01747 error occurs when Oracle cannot parse a column reference in a SQL statement. The column specification syntax is malformed — most often because a column name conflicts with an Oracle reserved word, the dotted-notation path is incorrect, a quoted identifier is improperly formed, or an UPDATE SET clause contains a structural error. This error is purely a parse-time failure and causes no data modification.
Common Causes
Section titled “Common Causes”1. Column Name Is an Oracle Reserved Word
Section titled “1. Column Name Is an Oracle Reserved Word”- Column named
DATE,LEVEL,ROWNUM,COMMENT,NUMBER, or other keywords - Application generates dynamic SQL with column names that clash with Oracle syntax
- Schema migrated from another RDBMS where keywords are not reserved
2. Incorrect Dotted-Notation Path
Section titled “2. Incorrect Dotted-Notation Path”- Four-part or deeper notation such as
schema.table.column.extrais not valid - Missing or extra dot in qualified column references
- Database link notation confused with column notation
3. Malformed UPDATE SET Clause
Section titled “3. Malformed UPDATE SET Clause”- Syntax error in the SET list of an UPDATE statement
- Missing comma between column assignments
- Using
=on the wrong side or inside a subquery incorrectly
4. Improperly Quoted Identifiers
Section titled “4. Improperly Quoted Identifiers”- Mixed or unmatched quote characters around column names
- Double-quote characters inside a single-quoted string literal
- Identifier case sensitivity issues when quotes are omitted
5. Dynamic SQL Generation Errors
Section titled “5. Dynamic SQL Generation Errors”- Application code building SQL strings with incorrect column lists
- ORM or report tool emitting non-standard column qualifications
- Concatenation error leaving an extra dot or colon in the statement
Diagnostic Queries
Section titled “Diagnostic Queries”Identify Reserved Word Conflicts
Section titled “Identify Reserved Word Conflicts”-- Check if a column name is an Oracle reserved wordSELECT keyword, reservedFROM v$reserved_wordsWHERE keyword = UPPER('&column_name')ORDER BY keyword;
-- List all reserved and non-reserved keywordsSELECT keyword, reserved, res_type, res_attr, res_semiFROM v$reserved_wordsWHERE reserved = 'Y'ORDER BY keyword;Inspect Column Names in a Table
Section titled “Inspect Column Names in a Table”-- Check actual column names for a tableSELECT column_name, data_type, nullable, column_idFROM user_tab_columnsWHERE table_name = UPPER('&table_name')ORDER BY column_id;
-- Find columns whose names match reserved wordsSELECT t.owner, t.table_name, t.column_name, r.keyword, r.reservedFROM dba_tab_columns tJOIN v$reserved_words r ON r.keyword = t.column_nameWHERE t.owner = USER AND r.reserved = 'Y'ORDER BY t.table_name, t.column_id;Review Recent Parse Failures
Section titled “Review Recent Parse Failures”-- Find statements that failed recently in shared poolSELECT sql_id, parse_calls, executions, sql_textFROM v$sqlWHERE sql_text LIKE '%ORA-01747%' OR (parse_calls > 0 AND executions = 0)ORDER BY last_active_time DESCFETCH FIRST 20 ROWS ONLY;
-- Check current session errorsSELECT *FROM v$sessionWHERE sid = SYS_CONTEXT('USERENV', 'SID');Step-by-Step Resolution
Section titled “Step-by-Step Resolution”1. Quote Reserved-Word Column Names
Section titled “1. Quote Reserved-Word Column Names”When a column name is a reserved word, always use double quotes around it in SQL:
-- If column is named DATE (a reserved word)-- BAD:SELECT id, DATE FROM my_table;
-- GOOD: quote the reserved word column nameSELECT id, "DATE" FROM my_table;
-- BAD UPDATE:UPDATE my_table SET DATE = SYSDATE WHERE id = 1;
-- GOOD UPDATE:UPDATE my_table SET "DATE" = SYSDATE WHERE id = 1;
-- Verify it works in a simple query firstSELECT "DATE", "COMMENT", "LEVEL"FROM my_tableWHERE ROWNUM <= 5;2. Fix Dotted-Notation Errors
Section titled “2. Fix Dotted-Notation Errors”Oracle supports at most three-part notation: schema.table.column.
-- BAD: four-part or incorrect notationSELECT t.schema.table.column FROM my_table t;
-- GOOD: correct alias and column referenceSELECT t.column_nameFROM schema_name.my_table t;
-- GOOD: fully qualified without aliasSELECT my_table.column_nameFROM my_tableWHERE my_table.id = 1;
-- GOOD: schema-qualifiedSELECT s.column_nameFROM schema_name.my_table sWHERE s.id = 1;3. Fix UPDATE SET Syntax
Section titled “3. Fix UPDATE SET Syntax”-- BAD: missing comma between assignmentsUPDATE employeesSET first_name = 'John' last_name = 'Smith' -- Missing comma causes ORA-01747WHERE employee_id = 100;
-- GOOD: proper comma-separated assignment listUPDATE employeesSET first_name = 'John', last_name = 'Smith'WHERE employee_id = 100;
-- BAD: reversed assignment in SETUPDATE employeesSET 'John' = first_nameWHERE employee_id = 100;
-- GOOD: column on left, value on rightUPDATE employeesSET first_name = 'John'WHERE employee_id = 100;4. Rename Reserved-Word Columns (Long-Term Fix)
Section titled “4. Rename Reserved-Word Columns (Long-Term Fix)”When you control the schema, rename offending columns to non-reserved names:
-- Rename a column that clashes with a reserved wordALTER TABLE my_table RENAME COLUMN "DATE" TO created_date;ALTER TABLE my_table RENAME COLUMN "COMMENT" TO remarks;ALTER TABLE my_table RENAME COLUMN "LEVEL" TO hierarchy_level;
-- Update dependent views and code after renaming-- Recompile any invalid objectsEXEC DBMS_UTILITY.COMPILE_SCHEMA(schema => USER, compile_all => FALSE);
-- Check for invalid objects after renameSELECT object_name, object_type, statusFROM user_objectsWHERE status = 'INVALID'ORDER BY object_type, object_name;5. Fix Dynamic SQL Column Lists
Section titled “5. Fix Dynamic SQL Column Lists”-- BAD: dynamic SQL with unquoted reserved-word columnDECLARE v_sql VARCHAR2(4000); v_col VARCHAR2(128) := 'DATE';BEGIN v_sql := 'SELECT ' || v_col || ' FROM my_table'; EXECUTE IMMEDIATE v_sql; -- Will raise ORA-01747END;/
-- GOOD: check and quote reserved words in dynamic SQLCREATE OR REPLACE FUNCTION safe_column_ref(p_col VARCHAR2) RETURN VARCHAR2 AS v_reserved NUMBER;BEGIN SELECT COUNT(*) INTO v_reserved FROM v$reserved_words WHERE keyword = UPPER(p_col) AND reserved = 'Y';
IF v_reserved > 0 THEN RETURN '"' || p_col || '"'; ELSE RETURN p_col; END IF;END;/
DECLARE v_sql VARCHAR2(4000);BEGIN v_sql := 'SELECT ' || safe_column_ref('DATE') || ' FROM my_table'; EXECUTE IMMEDIATE v_sql;END;/Prevention Strategies
Section titled “Prevention Strategies”1. Enforce Naming Standards
Section titled “1. Enforce Naming Standards”-- Trigger to prevent reserved-word column names at DDL time (12c+)-- Alternatively, use a naming convention audit querySELECT c.table_name, c.column_name, r.keywordFROM user_tab_columns cJOIN v$reserved_words r ON r.keyword = c.column_name AND r.reserved = 'Y'ORDER BY c.table_name;2. Code Review Checklist for SQL
Section titled “2. Code Review Checklist for SQL”- Always test generated SQL statements in SQL*Plus or SQL Developer before deploying
- Enable SQL parsing in application test suites to catch ORA-01747 before production
- Avoid column names that match any entry in
V$RESERVED_WORDS
3. Static Analysis Tools
Section titled “3. Static Analysis Tools”- Use Oracle SQL Developer’s code insight to flag reserved words used as identifiers
- Add a pre-commit hook that scans DDL files for reserved-word column names
- Review ORM entity definitions when mapping to legacy schemas with keyword columns
4. Character Set and Identifier Guidelines
Section titled “4. Character Set and Identifier Guidelines”-- Confirm identifier character set rules for the databaseSELECT *FROM nls_database_parametersWHERE parameter = 'NLS_CHARACTERSET';
-- Use DBMS_ASSERT to validate identifiers in dynamic SQLDECLARE v_safe_col VARCHAR2(128);BEGIN v_safe_col := DBMS_ASSERT.SIMPLE_SQL_NAME('my_column'); -- Raises ORA-44003 if not a valid simple SQL nameEND;/