问题
I have a rather large select which throws the ORA-01722: Invalid Number error. The error itself is clear but I don't know the exact line which throws it.
Is there any way to find out the exact line? I don't really want to look through the whole select and compare the types as it would take a very lone time.
回答1:
Most SQL clients will report the line and column where the error happened. If you don't have a good IDE handy, use DBMS_SQL.
SQL Client
Most SQL IDEs will highlight the line and column number of the error. Even SQL*Plus shows exactly where the invalid number error occurs:
SQL> select *
2 from dual
3 where 1 = 1
4 and 1 = 'a'
5 and 2 = 2;
and 1 = 'a'
*
ERROR at line 4:
ORA-01722: invalid number
(Unfortunately, Oracle SQL Developer does not provide this functionality.)
DBMS_SQL
If your choice of SQL tools is limited, you can still find the relevant line number using DBMS_SQL.LAST_ERROR_POSITION.
declare
v_sql clob := q'[
select *
from dual
where 1 = 1
and 1 = 'a'
and 2 = 2
]';
v_cursor integer;
v_ignore number;
begin
v_cursor := dbms_sql.open_cursor;
dbms_sql.parse(v_cursor, v_sql, dbms_sql.native);
v_ignore := dbms_sql.execute(v_cursor);
exception when others then
dbms_output.put_line(sqlerrm);
dbms_output.put_line('Error starts here: '||
substr(v_sql, dbms_sql.last_error_position));
end;
/
Results:
ORA-01722: invalid number
Error starts here: 'a'
and 2 = 2
(This answer assumes you can directly run the SQL statement. If the error is part of a PL/SQL program, then there's no easy way after the fact to find the line number inside a SQL statement, unless you're able to run it again through DBMS_SQL. The exact context is important here.)
回答2:
You have to do a binary search (ticking out half of columns, filter half of data) to find the column and line where the failure occures. Unfortunately there is no better way to debug a single SQL statement
回答3:
In most cases I've met there were 2 reasons for such a behaviour. Both are in WHERE area
When comparing a number against a string column, e.g.
where order_num = 2000
having order_num column defined as varchar2. In this case the execution crashes when it comes to order number like "1689_new" or so.
when comparing a number column against a string column,
where name = age
In the second case I got columns with similar name (table.order_num and table1.order_num) but having different datatype (varchar2 and number)
So I always check filter condition by commenting them out. First the hard coded values (see 1, above), then the column names.
The all_tab_cols is helpful for quick datatype check
来源:https://stackoverflow.com/questions/59749066/ora-01722-invalid-number-find-specific-line