Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, marko.

Asked: March 27, 2005 - 10:05 pm UTC

Last updated: April 20, 2005 - 6:57 am UTC

Version: any

Viewed 1000+ times

You Asked

If I run the following query in SQLPlus:

SQL> select *
2 from
3 testuser.emp22;
testuser.emp22
*
ERROR at line 3:
ORA-00942: table or view does not exist

SQLPlus somehow knows the line where the error is, i.e. it says "ERROR at line 3:".
Now the question is, can I get the same line number information if I'm using JDBC or is this functionality built into SQLPlus?

Thanks,
Marko


and Tom said...

OCI and other API's expose this, I could not find anything in JDBC (doesn't mean it is not there, just don't see it...)

However, you could call a stored procedure:


ops$tkyte@ORA9IR2> create or replace
2 function get_error_offset( p_query in varchar2 ) return number
3 authid current_user
4 as
5 l_theCursor integer default dbms_sql.open_cursor;
6 l_status integer;
7 begin
8 begin
9 dbms_sql.parse( l_theCursor, p_query, dbms_sql.native );
10 exception
11 when others then l_status := dbms_sql.last_error_position;
12 end;
13 dbms_sql.close_cursor( l_theCursor );
14 return l_status;
15 end;
16 /

Function created.

ops$tkyte@ORA9IR2> select *
2 from
3 testuser.emp22;
testuser.emp22
*
ERROR at line 3:
ORA-00942: table or view does not exist


ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> declare
2 n number;
3 str long := 'select *
4 from
5 testuser.emp22';
6 begin
7 n := get_error_offset( str );
8 dbms_output.put_line( substr( str, 1, n ) || '<<<<>>>>' || substr( str, n+1 ) );
9 end;
10 /
select *
from
testuser.<<<<>>>>emp22

PL/SQL procedure successfully completed.



Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Calling dbms_sql from java

marko, March 29, 2005 - 8:53 am UTC

So based on your answer, I'm assuming there is no way to call dbms_sql.parse diretly from Java?

Tom Kyte
March 29, 2005 - 10:30 am UTC

you could, but you would have to call

a) open
b) parse
c) get last error
d) close

you don't need a function, if that is what is bothering you. you can from jdbc just execute:

declare
l_theCursor integer default dbms_sql.open_cursor;
l_status integer;
begin
begin
dbms_sql.parse( l_theCursor, ?, dbms_sql.native );
exception
when others then l_status := dbms_sql.last_error_position;
end;
dbms_sql.close_cursor( l_theCursor );
? := l_status;
end;

in one call.

What about other querys

David C, April 18, 2005 - 12:23 pm UTC

get_error_offset is very useful but
when I try to find where a sentence like this is incorrect:
  drop * from fooo5 ( and fooo5 doesn't exits )

in sql-plus I obtain :
 
SQL> drop table fooo5
  2  ;
drop table fooo5
           *
ERROR a la lÝnia 1: 
//TRANSLATION: Error in line 1
ORA-00942: la taula o la vista no existeixen 
//TRANSLATION: Table or view does not exist

but the function get_error_offset returns a 0.

Why ? Can we found the exact error point?

Thanks,
 David C.

 

Tom Kyte
April 18, 2005 - 12:33 pm UTC

oh -- thanks for pointing that out

ouch, the get error offset should have this:

if (upper(substr(ltrim(?),1,6)) not in ( 'INSERT', 'UPDATE', 'DELETE', 'MERGE ', 'SELECT')
then
raise_application_error( -20001, 'not going to look' );
end if;


due to the fact that DDL is *executed* upon parse in DBMS_SQL. thank you so much for bringing that point up.

It would be unsafe to parse anything other than DML with this for that reason.

Then, there is nothing to do with not DML querys ?

David C., April 20, 2005 - 4:53 am UTC

Dear Tom,

SQLPlus do it, but now we only can found de error point in DML querys.

How we can find the error point with a PL (callable i.e. from Java or .NET) in drops, truncates or creates ?.
In order to merge it with get_error_offset.

Thank you very much.

David C.

Tom Kyte
April 20, 2005 - 6:57 am UTC

don't know that you can.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library