【问题标题】:Testing native dynamic SQL in Oracle before execution执行前在 Oracle 中测试原生动态 SQL
【发布时间】:2014-09-10 23:50:38
【问题描述】:

我在我的应用程序中实现了一个特定的功能,用户可以从用户界面通过推动按钮并在这里和那里插入一些值来动态地编写查询。

用户根本看不到生成的 SQL 语句。

我想知道是否有办法检查动态生成的 SQL 的语法和语法 (例如,他打开了一个括号 '(' 而忘记关闭它) 以确保没有 运行时编译错误会在使用EXECUTE IMMEDIATE 实际执行语句之前发生。

【问题讨论】:

    标签: oracle plsql dynamic-sql


    【解决方案1】:

    假设语句是 DML 而不是 DDL,您可以使用 dbms_sql.parse procedure 来解析 SQL 语句。使用 dbms_sql 包解析动态 SQL 语句然后使用 EXECUTE IMMEDIATE 执行它而不是使用 dbms_sql.execute 是相当不寻常的,但没有什么能阻止您混合使用 dbms_sqlexecute immediate

    只解析 SQL 语句的代码类似于

    DECLARE
      l_cursor integer;
      l_sql_stmt varchar2(1000) := <<some SQL statement>>;
    BEGIN
      l_cursor := dbms_sql.open_cursor;
      dbms_sql.parse( l_cursor, l_sql_stmt, dbms_sql.native );
      dbms_sql.close_cursor( l_cursor );
    END;
    

    【讨论】:

    • 你是对的,将两者混合不是一种常见的做法,但该程序似乎可以完成这项工作并且它是一个很好的权衡。加上名字说明了一切。谢谢。
    【解决方案2】:

    你也可以使用explain plan,这基本上是做执行的第一步。

    SQL> explain plan for select * from dual;
    
    Explained.
    

    SQL 是有效的,你也可以使用解释表来获取表、视图等,甚至是估计的运行时间……

    SQL> explain plan for select * from duall;
    explain plan for select * from duall
                                   *
    ERROR at line 1:
    ORA-00942: table or view does not exist
    

    SQL 无效,这就是为什么...

    你也可以在动态语句中使用它

    SQL> begin execute immediate  'explain plan for ' || ' select * from dual'; end;
      2  /
    
    PL/SQL procedure successfully completed.
    

    【讨论】:

    • 虽然我没有测试它,但它看起来像是一个可行的解决方案,但我选择了另一个解决方案,因为过程名称传达了它实际在做什么,而explain plan 的情况并非如此。谢谢。
    【解决方案3】:

    一如既往地使用错误处理,例如编写一个小的错误日志创建程序包或程序,你在需要时调用它。

    DECLARE
    
      my_stmt      VARCHAR2(4000):='this will contain my statements';
    
    BEGIN
    
      'begin' || my_stmt || 'end'; 
    
    EXCEPTION
     WHEN OTHERS THEN
       prc_my_error_log_creator();
    END;
    

    在 log_creator 中使用例如 DBMS_UTILITY.FORMAT_ERROR_BACKTRACE() 函数来获取堆栈的包含。

    问候

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-21
      • 2014-04-08
      • 1970-01-01
      • 1970-01-01
      • 2013-08-16
      • 1970-01-01
      • 2011-01-18
      • 1970-01-01
      相关资源
      最近更新 更多