DEV Community

umzzil nng
umzzil nng

Posted on • Originally published at oraerror.com

Oracle ORA-00928 Error: Causes and Solutions Complete Guide

ORA-00928: Missing SELECT Keyword — Causes, Fixes & Prevention

ORA-00928 is a SQL syntax error thrown by the Oracle parser when it encounters a position where a SELECT keyword is expected but finds something else entirely. This typically happens in INSERT ... SELECT statements, CREATE VIEW definitions, subqueries, or UNION blocks where the SELECT keyword has been accidentally omitted. It is one of the most common parse-time errors in Oracle and is almost always caused by a simple typo or copy-paste mistake.


Top 3 Causes

1. Missing SELECT in INSERT ... SELECT Statements

The most frequent trigger for ORA-00928 is forgetting to include SELECT in an INSERT ... SELECT statement.

-- BAD: Causes ORA-00928
INSERT INTO emp_backup (emp_id, emp_name, salary)
  emp_id, emp_name, salary
FROM employees
WHERE department_id = 10;

-- GOOD: Correct syntax
INSERT INTO emp_backup (emp_id, emp_name, salary)
SELECT emp_id, emp_name, salary
FROM employees
WHERE department_id = 10;
Enter fullscreen mode Exit fullscreen mode

2. Missing SELECT in CREATE VIEW or Subqueries

When creating a view or writing an inline view, the SELECT keyword must immediately follow the AS keyword or the opening parenthesis of a subquery.

-- BAD: Causes ORA-00928
CREATE OR REPLACE VIEW v_active_emp AS
  emp_id, emp_name
FROM employees
WHERE status = 'ACTIVE';

-- GOOD: Correct syntax
CREATE OR REPLACE VIEW v_active_emp AS
SELECT emp_id, emp_name
FROM employees
WHERE status = 'ACTIVE';

-- BAD inline view
SELECT a.emp_name
FROM employees a,
     (dept_id FROM departments WHERE location_id = 1800) b
WHERE a.department_id = b.dept_id;

-- GOOD inline view
SELECT a.emp_name
FROM employees a,
     (SELECT dept_id FROM departments WHERE location_id = 1800) b
WHERE a.department_id = b.dept_id;
Enter fullscreen mode Exit fullscreen mode

3. Missing SELECT in UNION / UNION ALL Blocks

In a UNION or UNION ALL query, every individual query block must begin with SELECT. Dropping it from any block — usually the second or third — triggers ORA-00928 immediately.

-- BAD: Causes ORA-00928
SELECT emp_id, emp_name, 'CURRENT' AS emp_status
FROM employees
UNION ALL
  emp_id, emp_name, 'RETIRED' AS emp_status
FROM retired_employees;

-- GOOD: SELECT present in every block
SELECT emp_id, emp_name, 'CURRENT' AS emp_status
FROM employees
UNION ALL
SELECT emp_id, emp_name, 'RETIRED' AS emp_status
FROM retired_employees;
Enter fullscreen mode Exit fullscreen mode

Quick Fix Solutions

  • Always check the first keyword of every query block — standalone queries, subqueries, CTE bodies, and each UNION branch must all start with SELECT.
  • Validate CTEs (WITH clauses) — every CTE body inside parentheses needs its own SELECT:
-- GOOD: CTE with proper SELECT
WITH dept_summary AS (
  SELECT dept_id, COUNT(*) AS emp_count
  FROM employees
  GROUP BY dept_id
)
SELECT d.dept_name, s.emp_count
FROM departments d
JOIN dept_summary s ON d.dept_id = s.dept_id;
Enter fullscreen mode Exit fullscreen mode
  • Use Oracle SQL Developer or Toad — both tools highlight missing keywords in real time before you even run the query.

Prevention Tips

  1. Build queries incrementally — write and test the innermost subquery first, confirm it runs cleanly, then wrap it in the outer query. This approach surfaces missing SELECT keywords at the earliest possible stage and avoids hunting through hundreds of lines of SQL.

  2. Adopt a SQL linter in your CI/CD pipeline — tools like SQLcl, SQLFluff, or IDE-level syntax checkers can be integrated into code review workflows to catch ORA-00928-class errors before they ever reach a production database.


Related Oracle Errors

Error Code Message When It Occurs
ORA-00900 invalid SQL statement Entire statement is unrecognizable
ORA-00923 FROM keyword not found FROM missing after SELECT list
ORA-00936 missing expression Expression missing in SELECT or WHERE
ORA-00907 missing right parenthesis Unclosed parenthesis in subquery

📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.

Top comments (0)