我有一个SQL语句(针对Oracle数据库),如果有效则执行需要很长时间,如果无效,则会立即返回一个错误。
我想通过JDBC,在“检查语句”按钮后面检查语法是否有效,而无需运行该语句。有没有厂商独立的方法可以做到这一点? 我最初的想法是将查询定义为PreparedStatement,但似乎没有任何编译或错误检查。
我有一个SQL语句(针对Oracle数据库),如果有效则执行需要很长时间,如果无效,则会立即返回一个错误。
我想通过JDBC,在“检查语句”按钮后面检查语法是否有效,而无需运行该语句。有没有厂商独立的方法可以做到这一点? 我最初的想法是将查询定义为PreparedStatement,但似乎没有任何编译或错误检查。
可能为该语句发出一个解释计划会给你有用的结果。
另一个想法——但可能更难的是编辑查询,添加 (and rownum < 1) 或其他内容以使其运行更快。
这更像是一个技巧而不是一个真正的答案,但是您可以运行一个查询,该查询始终返回一行一列:
SELECT ( EXISTS (SELECT 1 FROM dual)
OR
EXISTS (your Query here)
) AS result
FROM dual
如果您的查询有效,则应返回TRUE
,如果无效则应引发错误。
FROM dual
才有效。在其他数据库如SQL Server和Postgres中,你可以完全移除 FROM dual
,它仍然能正常工作。 - ypercubeᵀᴹDBMS_SQL.PARSE
来检查您的语句。警告:它只会解析DML语句,但会执行并提交DDL语句,如创建表等。您可以创建一个存储过程来返回值或布尔值,并包装一个类似于这样的块:set serveroutput on
-- Example of good SQL
declare
c integer;
s varchar2(50) := 'select * from dual';
begin
c := dbms_sql.open_cursor;
dbms_sql.parse(c,s,1);
dbms_sql.close_cursor(c);
dbms_output.put_line('SQL Ok');
exception
when others then
dbms_sql.close_cursor(c);
dbms_output.put_line('SQL Not Ok');
end;
/
-- Example of bad SQL
declare
c integer;
s varchar2(50) := 'select splat from dual';
begin
c := dbms_sql.open_cursor;
dbms_sql.parse(c,s,1);
dbms_sql.close_cursor(c);
dbms_output.put_line('SQL Ok');
exception
when others then
dbms_sql.close_cursor(c);
dbms_output.put_line('SQL Not Ok');
end;
/
你可以使用 Oracle 的 Pro*C 预编译器执行语法检查(在此下载)。
这是一个旨在预编译包含原始 Oracle SQL 语句的 C 代码的工具,但你可以"滥用"它来执行 SQL 语法检查。
创建一个名为test.pc的文件,并添加以下代码:
EXEC SQL SELECT * FROM DUAL WERE 1=1;
安装预编译工具后,运行以下命令:
proc INAME=test SQLCHECK=SYNTAX
您将看到以下输出:
Syntax error at line 1, column 34, file test.pc:
Error at line 1, column 34 in file test.pc
EXEC SQL SELECT * FROM DUAL WERE 1=1;
.................................1
PCC-S-02201, Encountered the symbol "1" when expecting one of the following:
; , for, union, connect, group, having, intersect, minus,
order, start, where, with,
The symbol "having," was substituted for "1" to continue.
将其整合到您的解决方案中应该很简单。
请注意,它还可以执行在线语义检查,验证特定模式中使用的所有过程和表是否有效。为此,您需要传递SQLCHECK=SEMANTICS USERID=youruser参数。