查找包含Oracle中语法错误的错误动态SQL语句

时间:2016-04-20 15:51:57

标签: oracle logging dynamic-sql

我想知道是否有办法找到在运行时执行中断的动态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会在系统视图中记录任何内容吗?

1 个答案:

答案 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语句,不执行它们。