我在我的应用程序中实现了某个功能,用户可以通过按下按钮并在此处插入一些值来动态地从用户界面编写查询。
用户根本不会看到生成的SQL语句。
我想知道是否有办法可以检查语法和语法(例如,他打开动态生成的SQL的'parantheses'('并忘了关闭它)以确保没有<在使用EXECUTE IMMEDIATE实际执行语句之前,会发生强>运行时编译错误。
答案 0 :(得分:5)
假设语句是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;
答案 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()函数来获取堆栈的内容。
此致