Oracle ORA-00933: SQL command not properly ended - oracle

I try to use golang and query data from Oracle. My SQL query is:
SELECT * FROM TABLE1 OFFSET 10 ROWS;
But it gives an error:
EXTRA *errors.withStack=dpiStmt_execute: ORA-00933: SQL command not properly ended
My SQL query works fine when I query in SQL*Plus, but errors when I use golang.

I'd try running the query without the terminating semicolon, as Alex Poole pointed out. A lot of Oracle client libraries (i.e. cx_Oracle in python, ADO.NET Oracle Libraries) do complain if you try to execute a query ending with the semicolon (which is perfectly legal in SQL/Plus)

If the offset is not specified, it is assumed that it is 0 (zero). So, remove that clause (as it does nothing in your case), i.e.
select * from table1
and use that query in golang.

I am pretty sure that just your closing semicolon is to much. The semicolon is a character to separate several SQL statements or to close a pl/sql block. So when you write it at the end of a SQL statement the parser doesn't know how to handle it, cause he only awaits a single SQL statement.

Related

Jmeter with Oracle 12c: the ";" is unusable

I have a jMeter 3.0 to oracle 12 c using thin connection (used ojdbc 7 and 7_c) and I cannot use the row end line ( ; ). It always returns
Cannot create PoolableConnectionFactory (ORA-00933: SQL command not properly ended
If I remove the ";" from the query everything goes fine. How can I fix this?
I found a workaround for this that avoids having the semi-colon problem:
JDBC Request Query Type needs to be: Update Statement
The query needs to be processed as a block
BEGIN
SQL Statement
END;
There are specific SQL structures that can't be executed as a block but still this enables having legit SQL code within the request and enhances having several statements in the same request.
If you are using JDBC_Request Sampler, you should NOT keep semi-colon as a trailing at the end of a line for SQL query,
Do not enter a trailing semi-colon.
so, without semi-colon, it should work properly and no need to include that.
Reference:
http://jmeter.apache.org/usermanual/component_reference.html#JDBC_Request

Running multi-statement query using JDBC on DB2 windows

I am trying to run multi-statement queries using JDBC on DB2 10.1 Windows but it fails with a syntax error. Following is the query-
SELECT * FROM schemaname.tablename;
Exception in thread "main" com.ibm.db2.jcc.am.SqlSyntaxErrorException: An unexpected token "" was found following "". Expected tokens may include: "schemaname.tablename".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.13.127
I understand that this comes due to the semi-colon at the end of the query which is not understand by the database. How can I set the query separator as semicolon so get through this.
With JDBC you execute one statement at a time; by the looks of it DB2 doesn't support it. Some drivers/databases have a way around this, but it is non-standard.
So instead of trying to execute two statements in one go, you will need to execute them one after the other.

ORA-00907 when quering from my Java application but works fine in SQL Developer

My query that I put into a prepared statement is:
select *
from ( select seq, audit_ts, message_type
from log2
where 1 = 1
and message_type in ('SOURCE', 'DEST')
order by seq desc )
where ROWNUM <= ?
When I run the query in my application, I get:
java.sql.SQLSyntaxErrorException: ORA-00907: missing right parenthesis
EDIT: Here is the java executing the query. I am trying to return a set of search results, so the prefix contains the SELECT statement and then I can have any number of suffixes (in this excerpt "AUDIT_LOG_SEARCH2") which are the parameterized WHERE clauses based on the user search:
StringBuffer query = new StringBuffer(300);
query.append(dbAdapter.getQuery("AUDIT_LOG_ENTRY_PREFIX"));
query.append(dbAdapter.getQuery("AUDIT_LOG_SEARCH2"));
// Insert parameters to complete the sql prepared statement
PreparedStatement ps = _dbConn.prepareStatement(query.toString());
ResultSet rs = ps.executeQuery();
But the query runs fine when I run it separately in SQL Developer. The query was originally created for Postgres, then updated for Oracle. Any tips?
You need to set the variables into the preparedStatement before executing.
PreparedStatement ps = _dbConn.prepareStatement(query.toString());
ps.setInt(1, 10);
Please post what query.toString() gives you if that doesn't work. Not query, but query.toString()
What are you doing in your:
// Insert parameters to complete the sql prepared statement
Are you using correctly the methods ps.setString... or whatever? Or are you just replacing the question marks? the second might be corrupting your query.
Based on #AlexPoole and #EdGibbs comments, I decided to add a bunch more debug statements. It turns out the method was being recursively called with a different sql "suffix" later on in the program if certain conditions were met. The suffix was not updated with the necessary parenthesis for the new ROWNUM wrapping the statement. So although the ORA-00907 can be thrown for many different formatting problems, it was in fact a right parenthesis that was causing me problems :P
The prefix and suffix seems like a weird pattern in this code base for creating sql queries. I'm thinking of getting rid of this and refactoring so queries don't have to be built like that. Any advice??
So for anyone else who runs into this Oracle error, I would suggest logging the sql statement you are generating and play around with it in SQL Developer. If it works in there, but not in your application, your code is probably doing something funky :P

oracle SQL plus how to end command in SQL file?

I have SQL file with few commands.
What it the correct way to end lines in the script?
Is it slash [/] semicolon [;] both?
Is there any diffarent between regular sqls and Stored procedure code?
Thank you
For normal SQL statements, either a / on a line by itself, or a ; at the end of the command, will work fine.
For statements that include PL/SQL code, such as CREATE FUNCTION, CREATE PROCEDURE, CREATE PACKAGE, CREATE TYPE, or anonymous blocks (DECLARE/BEGIN/END), a ; will not execute the command. Since PL/SQL uses semicolons as line terminators, its use as a command terminator must be suppressed in these statements. So in these cases, you must use / to execute the command.
In my experience, people prefer to use the semicolon when possible and use the slash only when required.
Note that for SQLPlus client commands -- such as SET or EXECUTE -- no command terminator is necessary at all, although people often end them with a semicolon out of habit.
; is the way you should end your sql commands, same goes for PLSQL procedures:
select * from dual;
select sysdate from dual;
select table_name from user tables;
exec dbms_output.putline('Hello');
Usually we can use ";" to end sql statement,
but for create functions, triggers, procedures you have to use "/" after ";" to end SQL statement.
"/" might not be required when you use some developers tool like, oracle SQL developer, toad etc, but it should be mandate when you execute your query directly in the linux machine.

How do I debug Oracle dynamic sql in sqlplus?

I have a PL/SQL statement that uses EXECUTE IMMEDIATE to execute a query. However, I'm having difficulty figuring out how to even get the text of the query that's being executed. I can't use dbms_output as the query is greater than 255 characters. Is there any way to make sqlplus echo the string that's passed in to EXECUTE IMMEDIATE?
What version of Oracle are you using? 255 is the default line length for DBMS_OUTPUT.PUT_LINE(). Before 10g we could display 1048 characters in a single call. Since then it is 32K.
Alternatively you should consider using an IDE which supports DBMS_DEBUG. For instance, SQL Developer does so, and it is free from Oracle. Find out more.
You can try to attach a profiler to the database (honestly I have only done that for SqlServer) and run the procedure since the profiler will show any query made to the DB you will be able to pick it up there and do the necessary debugging.
Hope it helps..
How to print large strings N characters at a time.
Modify to suit your needs.
FOR i IN 0..10 LOOP
dbms_output.put_line(substr(my_very_long_string,i*100+1,100));
END LOOP;
You could insert the string into a logging/temporary table and examine it.

Resources