How to Fix ORA-00911: Invalid Character in Oracle

Find the character behind ORA-00911, often syntax from MySQL or JDBC, and rewrite it the Oracle way.

ORA-00911 means the SQL text contains a character that has no meaning at that position in Oracle SQL. It often comes from SQL written for another database or tool: a # comment from MySQL, a ? placeholder from JDBC, or a stray backslash. In Oracle AI Database 26ai the message shows the character and what came before it, which makes the culprit easy to find.

Reproduce the Error

Each statement is run with EXECUTE IMMEDIATE, so Oracle receives the text exactly as written, and the error message is printed:

Example:

-- each statement is sent exactly as written, through dynamic SQL
declare
  type t_list is table of varchar2(200);
  v_sql t_list := t_list(
    'select count(*) from dual # MySQL-style comment',
    'select count(*) from dual where dummy = ?',            -- JDBC-style placeholder
    'select count(*) from dual where 1 = 1 \');
  v_n number;
begin
  for i in 1 .. v_sql.count loop
    begin
      execute immediate v_sql(i) into v_n;
    exception
      when others then dbms_output.put_line(sqlerrm);
    end;
  end loop;
end;
/

Output:

ORA-00911: #: invalid character after DUAL
ORA-00911: ?: invalid character after =
ORA-00911: \: invalid character after <number>

PL/SQL procedure successfully completed.
  • # starts a comment in MySQL, but not in Oracle.
  • ? is a placeholder in JDBC and ODBC; Oracle SQL text uses named binds such as :d.
  • A backslash has no meaning in Oracle SQL outside a string.

Fix: Use Oracle Syntax

Write comments with -- or /* */, and bind values with named placeholders and USING:

Example:

declare
  v_n number;
begin
  -- an Oracle comment, and a named bind variable with USING
  execute immediate 'select count(*) from dual where dummy = :d -- a comment'
    into v_n using 'X';
  dbms_output.put_line('rows: ' || v_n);
end;
/

Output:

rows: 1

PL/SQL procedure successfully completed.

Other Common Causes

  • Characters pasted from documents or web pages, such as curly quotes or non-breaking spaces; in the test, curly quotes around a value gave ORA-01756 instead, quoted string not properly terminated.
  • Special characters such as $ or # at the start of an unquoted name; they are allowed only after the first character.
  • In older releases, a semicolon at the end of a statement passed to EXECUTE IMMEDIATE raised ORA-00911; Oracle AI Database 26ai accepted it in the test.

Things to Know

  • Client tools such as SQLcl and SQL*Plus interpret some characters themselves before sending the statement, so test generated SQL the way the application sends it.
  • Retype quotes and minus signs in SQL copied from formatted documents.

Related Guides

Conclusion

ORA-00911 points to a character Oracle does not accept where it appears, usually syntax from another database or text pasted from a document. Read the character from the message, then use Oracle comments, named binds, and plain quotes.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE, author of four books on Oracle APEX, SQL and PL/SQL, and Oracle Forms, and a software developer building Oracle database applications since 2001.

guest

0 Comments
Oldest
Newest Most Voted