在执行之前在Oracle中测试本机动态SQL

时间:2014-07-20 08:33:59

标签: oracle plsql dynamic-sql

我在我的应用程序中实现了某个功能,用户可以通过按下按钮并在此处插入一些值来动态地从用户界面编写查询。

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

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

3 个答案:

答案 0 :(得分:5)

假设语句是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;

答案 1 :(得分:3)

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

SQL> explain plan for select * from dual;

Explained.

SQL是有效的,您也可以使用explain表来获取表,视图等,甚至可以估算运行时间......

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.

答案 2 :(得分:0)

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

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()函数来获取堆栈的内容。

此致