Используйте DBMS_SQL
вместо собственного динамического SQL, а затем используйте DBMS_SQL.LAST_ERROR_POSITION()
для идентификации части оператора с ошибкой.
DBMS_SQL
менее удобно, чем собственный динамический SQL, но такжеболее могущественный.Есть несколько ошибок, на которые стоит обратить внимание.Во-первых, процедура DBMS_SQL.PARSE
не только анализирует команды, но и автоматически запускает команды DDL.
Приведенный ниже код пытается создать таблицу с использованием двух других таблиц, одна из которых, очевидно, не существует.,Регулярное выражение используется для вывода каждого символа с позиции ошибки в первый пробел.(Этот код основан на этом ответе. )
declare
v_cursor_id integer := dbms_sql.open_cursor ();
v_sql varchar2(32767) := q'[
create table zzz_temp as
select *
from dual
join some_schema.fake_table
on dual.dummy = fake_table.dummy
]';
begin
dbms_sql.parse(v_cursor_id, v_sql, dbms_sql.native);
dbms_sql.close_cursor(v_cursor_id);
exception
when others then
dbms_output.put_line
(
sqlerrm||chr(10)||
'Error occurred here: '||
regexp_substr
(
srcstr => v_sql,
pattern => '\w+',
position => dbms_sql.last_error_position()
)
);
dbms_sql.close_cursor(v_cursor_id);
end;
/
DBMS_OUTPUT:
ORA-00942: table or view does not exist
Error occurred here: fake_table
Некоторые другие предложения случайных кодов:
- Используйте
PARALLEL(4)
вместо PARALLEL(A, 4)
.Параллелизм на уровне операторов почти всегда лучше параллелизма на уровне объектов.Если вы запустите одну таблицу параллельно, вы, вероятно, захотите выполнить весь запрос параллельно. - Старайтесь избегать
WHEN OTHERS
.Если возможно, используйте более конкретный обработчик ошибок.