我想知道是否有办法找到在运行时执行中断的动态SQL语句,以防在调用dynanic SQL的PL / SQL程序单元中没有正确的异常处理。
procedure will_crash is
begin
-- 1000 dynamic sql statements here ..
execute immediate 'updaXte dual set X = ''Z'' ' ;
-- ... and 1000 more dynamic sql statements here ..
commit;
end; --> NO proper exception handling for logging the last sql statement
如果一个夜间预定程序单元包含数百个动态sql语句,我想知道哪一个没有调试就破坏了。 Oracle会在系统视图中记录任何内容吗?
答案 0 :(得分:0)
在您的示例中,根本不需要使用动态SQL,因此最简单的解决方案是将其重写为
procedure will_crash is
begin
-- 1000 dynamic sql statements here ..
updaXte dual set X = ''Z''; -- Error at compile time!!
-- ... and 1000 more dynamic sql statements here ..
commit;
end; --> NO proper exception handling for logging the last sql statement
如果实际过程使用动态SQL,因为SQL语句保存在别处(变量或SQL表),而我们只讨论语法错误,那么在使用DBMS_SQL包执行语句之前,可以实现目标。 这是一个例子:
DECLARE
lc_good VARCHAR2(200) := 'SELECT 1 FROM dual';
lc_bad VARCHAR2(200) := 'SEL1ECT a FROM dual';
lc_cursor NUMBER;
BEGIN
lc_cursor := SYS.DBMS_SQL.OPEN_CURSOR;
BEGIN
SYS.DBMS_SQL.PARSE(lc_cursor, lc_good, DBMS_SQL.V7);
dbms_output.put_line('Statement 1 is GOOD');
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Statement 1 is BAD: ' || SQLERRM);
END;
BEGIN
SYS.DBMS_SQL.PARSE(lc_cursor, lc_bad, DBMS_SQL.V7);
dbms_output.put_line('Statement 2 is GOOD');
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Statement 2 is BAD: ' || SQLERRM);
END;
SYS.DBMS_SQL.close_cursor(lc_cursor);
END;
功能输出如下:
Statement 1 is GOOD
Statement 2 is BAD: ORA-00900: ...
请注意,代码只解析SQL语句,不执行它们。