Skip to content

ORA-00933 SQL Command Not Properly Ended - Statement Termination Fixes

Error Text: ORA-00933: SQL command not properly ended

This error occurs when Oracle encounters an SQL statement that is syntactically incomplete or improperly terminated. It’s commonly caused by missing keywords, incorrect statement structure, or unsupported SQL syntax in the current context.

-- SELECT statement structure
SELECT column_list
FROM table_name
[WHERE condition]
[GROUP BY columns]
[HAVING condition]
[ORDER BY columns];
-- INSERT statement structure
INSERT INTO table_name (column_list)
VALUES (value_list);
-- UPDATE statement structure
UPDATE table_name
SET column = value
[WHERE condition];
  • SQL statements must end with semicolon (;) in scripts
  • DDL statements cannot be mixed with DML in some contexts
  • Some statements require specific syntax order
-- Missing FROM keyword
SELECT col1, col2 table_name; -- ERROR
-- Missing INTO keyword in INSERT
INSERT table_name (col1, col2) VALUES (val1, val2); -- ERROR
-- Missing SET keyword in UPDATE
UPDATE table_name col1 = 'value' WHERE id = 1; -- ERROR
-- Correct SELECT with FROM
SELECT col1, col2 FROM table_name;
-- Correct INSERT with INTO
INSERT INTO table_name (col1, col2) VALUES (val1, val2);
-- Correct UPDATE with SET
UPDATE table_name SET col1 = 'value' WHERE id = 1;
-- ORDER BY in subquery (not allowed in most contexts)
SELECT * FROM table1 WHERE id IN (
SELECT id FROM table2 ORDER BY name -- ERROR
);
-- ORDER BY in view definition
CREATE VIEW my_view AS
SELECT * FROM table1 ORDER BY col1; -- ERROR in most cases
-- Remove ORDER BY from subquery
SELECT * FROM table1 WHERE id IN (
SELECT id FROM table2
);
-- ORDER BY in outer query instead
SELECT * FROM table1 WHERE id IN (
SELECT id FROM table2
) ORDER BY name;
-- Use ROW_NUMBER() for ordered subquery results
SELECT * FROM table1 WHERE id IN (
SELECT id FROM (
SELECT id, ROW_NUMBER() OVER (ORDER BY name) rn
FROM table2
) WHERE rn <= 10
);
-- Invalid column definition
CREATE TABLE test_table (
id NUMBER,
name VARCHAR2(50)
description VARCHAR2(200) -- Missing comma
);
-- Invalid constraint syntax
ALTER TABLE test_table ADD CONSTRAINT pk_test PRIMARY KEY id; -- Missing parentheses
-- Correct table creation
CREATE TABLE test_table (
id NUMBER,
name VARCHAR2(50),
description VARCHAR2(200)
);
-- Correct constraint syntax
ALTER TABLE test_table ADD CONSTRAINT pk_test PRIMARY KEY (id);
-- Non-Oracle SQL syntax
SELECT TOP 10 * FROM table_name; -- SQL Server syntax, not Oracle
-- Incorrect LIMIT usage
SELECT * FROM table_name LIMIT 10; -- MySQL syntax, not Oracle
-- Invalid JOIN syntax
SELECT * FROM table1, table2 JOIN table3 ON condition; -- Mixed syntax error
-- Oracle equivalent using ROWNUM
SELECT * FROM table_name WHERE ROWNUM <= 10;
-- Or using FETCH FIRST (12c+)
SELECT * FROM table_name FETCH FIRST 10 ROWS ONLY;
-- Proper JOIN syntax
SELECT * FROM table1
JOIN table2 ON table1.id = table2.id
JOIN table3 ON table2.ref_id = table3.id;
-- Break down complex statements
-- Original problematic query:
SELECT col1, col2 FROM table1 WHERE col3 = 'value' ORDER BY col1 UNION SELECT col1, col2 FROM table2;
-- Issue: ORDER BY cannot be used before UNION
-- Fixed version:
SELECT col1, col2 FROM table1 WHERE col3 = 'value'
UNION
SELECT col1, col2 FROM table2
ORDER BY col1;
-- Use EXPLAIN PLAN to validate syntax
EXPLAIN PLAN FOR
SELECT * FROM table_name WHERE condition;
-- Check for parsing errors
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
-- Start with basic statement
SELECT * FROM table_name;
-- Add clauses one by one
SELECT * FROM table_name WHERE condition;
-- Add more complexity
SELECT col1, col2 FROM table_name WHERE condition ORDER BY col1;
-- SQL statement in PL/SQL block
BEGIN
-- This will cause ORA-00933
SELECT * FROM table_name ORDER BY col1; -- ERROR: No INTO clause
-- Correct version with INTO
SELECT col1 INTO v_variable FROM table_name WHERE id = 1;
-- Or use cursor
FOR rec IN (SELECT * FROM table_name ORDER BY col1) LOOP
-- Process records
NULL;
END LOOP;
END;
/
-- Invalid view with ORDER BY
CREATE VIEW my_view AS
SELECT * FROM table_name ORDER BY col1; -- Often causes ORA-00933
-- Valid view without ORDER BY
CREATE VIEW my_view AS
SELECT * FROM table_name;
-- Order when selecting from view
SELECT * FROM my_view ORDER BY col1;
-- Invalid subquery syntax
SELECT * FROM (
SELECT * FROM table_name ORDER BY col1 -- Missing FROM in outer query
);
-- Correct subquery syntax
SELECT * FROM (
SELECT * FROM table_name ORDER BY col1
) subquery_alias;
-- Original problematic query
SELECT t1.col1, t2.col2
FROM table1 t1, table2 t2
WHERE t1.id = t2.id
GROUP BY t1.col1
ORDER BY t1.col1
UNION
SELECT t3.col1, t4.col2
FROM table3 t3, table4 t4
WHERE t3.id = t4.id; -- ERROR: ORDER BY before UNION
-- Restructured correct version
SELECT col1, col2 FROM (
SELECT t1.col1, t2.col2
FROM table1 t1, table2 t2
WHERE t1.id = t2.id
GROUP BY t1.col1
UNION
SELECT t3.col1, t4.col2
FROM table3 t3, table4 t4
WHERE t3.id = t4.id
)
ORDER BY col1;
-- Validate dynamic SQL before execution
CREATE OR REPLACE PROCEDURE validate_sql(p_sql CLOB) AS
l_cursor NUMBER;
l_result NUMBER;
BEGIN
l_cursor := DBMS_SQL.OPEN_CURSOR;
BEGIN
DBMS_SQL.PARSE(l_cursor, p_sql, DBMS_SQL.NATIVE);
DBMS_OUTPUT.PUT_LINE('SQL syntax is valid');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('SQL Error: ' || SQLERRM);
END;
DBMS_SQL.CLOSE_CURSOR(l_cursor);
EXCEPTION
WHEN OTHERS THEN
IF DBMS_SQL.IS_OPEN(l_cursor) THEN
DBMS_SQL.CLOSE_CURSOR(l_cursor);
END IF;
RAISE;
END;
/
-- Follow consistent SQL formatting
SELECT
col1,
col2,
col3
FROM table_name
WHERE condition1 = 'value1'
AND condition2 = 'value2'
GROUP BY col1, col2
HAVING COUNT(*) > 1
ORDER BY col1, col2;
-- Use development tools with syntax checking
-- Validate statements before execution
-- Test complex queries in parts
-- Implement SQL code review checklist:
-- 1. Check statement termination
-- 2. Verify keyword order
-- 3. Validate subquery syntax
-- 4. Confirm context-appropriate syntax
-- 5. Test with sample data
-- Simple syntax check
SET SERVEROUTPUT ON
DECLARE
l_sql VARCHAR2(4000) := 'YOUR_SQL_STATEMENT_HERE';
l_cursor NUMBER;
BEGIN
l_cursor := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(l_cursor, l_sql, DBMS_SQL.NATIVE);
DBMS_OUTPUT.PUT_LINE('Syntax OK');
DBMS_SQL.CLOSE_CURSOR(l_cursor);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
IF DBMS_SQL.IS_OPEN(l_cursor) THEN
DBMS_SQL.CLOSE_CURSOR(l_cursor);
END IF;
END;
/
  • ORA-00907: Missing right parenthesis
  • ORA-00936: Missing expression
  • ORA-00904: Invalid identifier
  • ORA-01756: Quoted string not properly terminated
  1. Use consistent SQL formatting and style
  2. Validate syntax in development tools
  3. Test complex queries incrementally
  4. Follow Oracle SQL standards
  5. Implement proper code review processes
  6. Use appropriate syntax for the context
  • Check for missing keywords (FROM, INTO, SET)
  • Verify statement structure and order
  • Remove invalid ORDER BY in subqueries
  • Confirm Oracle-compatible syntax
  • Validate DDL statement format
  • Check for context-appropriate SQL
  • Test statement components individually
  • Review for proper statement termination