【发布时间】:2014-09-10 23:50:38
【问题描述】:
我在我的应用程序中实现了一个特定的功能,用户可以从用户界面通过推动按钮并在这里和那里插入一些值来动态地编写查询。
用户根本看不到生成的 SQL 语句。
我想知道是否有办法检查动态生成的 SQL 的语法和语法 (例如,他打开了一个括号 '(' 而忘记关闭它) 以确保没有 运行时编译错误会在使用EXECUTE IMMEDIATE 实际执行语句之前发生。
【问题讨论】:
标签: oracle plsql dynamic-sql
我在我的应用程序中实现了一个特定的功能,用户可以从用户界面通过推动按钮并在这里和那里插入一些值来动态地编写查询。
用户根本看不到生成的 SQL 语句。
我想知道是否有办法检查动态生成的 SQL 的语法和语法 (例如,他打开了一个括号 '(' 而忘记关闭它) 以确保没有 运行时编译错误会在使用EXECUTE IMMEDIATE 实际执行语句之前发生。
【问题讨论】:
标签: oracle plsql dynamic-sql
假设语句是 DML 而不是 DDL,您可以使用 dbms_sql.parse procedure 来解析 SQL 语句。使用 dbms_sql 包解析动态 SQL 语句然后使用 EXECUTE IMMEDIATE 执行它而不是使用 dbms_sql.execute 是相当不寻常的,但没有什么能阻止您混合使用 dbms_sql 和 execute 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;
【讨论】:
你也可以使用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 的情况并非如此。谢谢。
一如既往地使用错误处理,例如编写一个小的错误日志创建程序包或程序,你在需要时调用它。
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() 函数来获取堆栈的包含。
问候
【讨论】: