Skip to content
Oracle Database

Oracle Error ORA-00936

missing expression

Applies to: Oracle Database 19c, 21c, 23ai and 26ai (same wording)
Last technically reviewed 24 October 2026 on Oracle Database Error Messages reference (26ai, 21c and 19c); not run locally
The full message
ORA-00936: missing expression
Other forms of this message
SQL*Plus and SQLcl mark where the expression is missing
SELECT id, email, FROM customers
                  *
ERROR at line 1:
ORA-00936: missing expression
Error code
ORA-00936
Product
Oracle Database
Versions
Oracle Database 19c, 21c, 23ai and 26ai (same wording)
Last reviewed
24 October 2026

What it means

ORA-00936 means Oracle expected a value, column or other expression at some point in the statement and found nothing usable there: typically a trailing comma, an empty select list, or a comparison with nothing on one side.

Oracle's reference describes it as a required part of a clause or expression that has been omitted, for example a SELECT entered without a list of columns or with an incomplete expression. It is also raised when a reserved word is misused where an expression should be, as in SELECT TABLE. The parser knows an expression must come next and the next token cannot start one.

Hand-written SQL usually fails because of a comma before FROM or a half-finished condition. In generated or dynamically built SQL, the usual cause is an empty variable: a value, a column name or a list for IN that was blank when the string was assembled, leaving WHERE customer_id = AND ... or IN () behind.

Common causes

  • A trailing comma at the end of the SELECT list, just before FROM, or a doubled comma.
  • A comparison or operator with nothing on one side, such as WHERE total > or a dangling AND.
  • Dynamic SQL built from an empty variable, leaving a gap where a value, column or IN list should be.
  • A reserved word used where an expression should be, or a SELECT with no columns at all.
  • A function call or CASE expression left incomplete, for example an empty argument between commas.

Diagnose it

Read-only These queries only read the data dictionary (USER_, ALL_ and DBA_ views) and dynamic performance views (V$). They do not change data, privileges or settings, so they are safe to run first. DBA_ and V$ views need the matching privileges.

Look just before the position Oracle marks

The asterisk in SQL*Plus or SQLcl, or the line and column in your tool, marks where Oracle expected an expression. Look at the token immediately before it: a comma, an operator, an opening bracket or a keyword such as WHERE or AND that needs something after it.

Log the final text of generated SQL

For SQL built in code, print or log the exact statement just before it runs (with the bind values listed separately). A gap such as "= AND", "IN ()" or ", FROM" is then easy to see, and you can trace it back to the empty variable.

Is the word a reserved word?

If a column is named with a word Oracle reserves, it cannot be used unquoted. V$RESERVED_WORDS needs SELECT_CATALOG_ROLE or a grant from the DBA; otherwise see the reserved words list in the SQL Language Reference.

SELECT keyword, reserved
FROM v$reserved_words
WHERE keyword IN ('TABLE', 'LEVEL', 'SIZE');
What to look for

RESERVED = Y means the word cannot be used as an unquoted identifier.

How to fix it

Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.

Remove the stray comma or complete the expression

Read-only

The usual fix: delete the comma before FROM, or supply the missing value or column. Putting each select-list item on its own line makes a dangling comma obvious.

SELECT id,
       email
FROM shop.customers
WHERE created_at >= DATE '2026-01-01';

Bind values instead of concatenating them

Client or network side

With bind variables the statement text never changes, so an empty value becomes NULL (and no rows match) rather than a syntax error. Handle the empty case explicitly in code, for example by leaving out the condition.

SELECT id, order_date, total
FROM shop.orders
WHERE customer_id = :customer_id
  AND status = :status

Guard optional conditions and empty IN lists in dynamic SQL

Client or network side

When a filter is optional, add the whole condition only if the value is present, rather than adding "AND col = " and an empty value. For an IN list with no items, skip the query or the condition: IN () is never valid.

Examples

A trailing comma before FROM

Not reproduced here: no Oracle Database is installed for this site. The message text comes from Oracle's error reference and is the same in 19c and current releases; Oracle expected another select-list item after the last comma.

SELECT id, email, FROM customers;
Expected result (documented format, not run)
ORA-00936: missing expression

Dynamic SQL with an empty value

Not reproduced here: no Oracle Database is installed for this site. The message text comes from Oracle's error reference, which describes the cause as a required part of an expression being omitted; here the value after "=" is missing. Bind variables avoid this, and also protect against SQL injection.

-- built in code as: 'WHERE customer_id = ' || v_id || ' AND status = ''OPEN'''
-- with v_id empty, the database receives:
SELECT id, order_date
FROM orders
WHERE customer_id =  AND status = 'OPEN';
Expected result (documented format, not run)
ORA-00936: missing expression

How to prevent it

Format select lists and conditions one item per line so stray and missing commas stand out, and run a formatter before reviewing long statements. Use the SQL formatter on queries pasted from logs.

In application code, build SQL with bind variables and add optional conditions as whole fragments, never as half-written ones. Test the empty and missing-value cases of every search screen and report filter.

Common questions

How do I fix ORA-00936 missing expression?

Look just before the position Oracle marks. Remove a trailing comma before FROM, complete the comparison or function call, and in dynamic SQL make sure no variable that should hold a value or list is empty.

Why do I get ORA-00936 only from my application?

The SQL is probably built from strings, and one of the variables is empty for some inputs, leaving a gap such as "= AND" or "IN ()". Log the final statement text and switch to bind variables.

What is the difference between ORA-00936 and ORA-00933?

ORA-00936 means something required is missing, so Oracle could not finish an expression. ORA-00933 means Oracle finished the statement and then found extra text, such as a clause it does not support.

Learn more on CodeWithSQL

Official documentation

Last technically reviewed 24 October 2026; examples and diagnostics run on Oracle Database Error Messages reference (26ai, 21c and 19c); not run locally. Messages and explanations follow Oracle's Database Error Messages reference; no Oracle Database was available, so the examples were not run locally.

Still stuck on an Oracle error?

Browse the full Oracle error library, or get hands-on help from an experienced SQL professional.