我有一个SQL语句(对于Oracle数据库)如果有效则需要很长时间才能运行。如果它无效,则立即返回错误。
我想检查语法是否有效而不运行语句(通过JDBC),例如在'check statement'按钮后面。是否有独立于供应商的方式?我首先想到的只是将查询定义为PreparedStatement似乎不会导致任何类型的编译或错误检查。
答案 0 :(得分:11)
可能会为该陈述发布解释计划,这将为您提供有用的结果。
另一个想法 - 但可能更难的是编辑要添加的查询(和rownum< 1)或其他东西以使其快速运行
答案 1 :(得分:5)
这更像是一个黑客而不是真正的答案,但你可以运行一个总是返回一行和一列的查询:
SELECT ( EXISTS (SELECT 1 FROM dual)
OR
EXISTS (your Query here)
) AS result
FROM dual
如果您的查询有效,则应返回TRUE
,如果无效则会引发错误。
答案 2 :(得分:5)
如果您正在处理SELECT查询,那么JDBC PreparedStatement#getMetaData可能会起作用吗?
答案 3 :(得分:2)
您可以使用DBMS_SQL.PARSE
来检查您的陈述。 警告:它只会解析DML语句,但它会执行并提交DDL语句,例如create table等。您可以创建一个存储过程来返回一个值或布尔值,并像这样包装一个块: / p>
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;
/
答案 4 :(得分:0)
您可以使用Oracle's Pro*C precompiler执行语法检查(download here)。
这是一个用于预编译包含原始Oracle SQL语句的C代码的工具,但您可以“滥用”它来执行SQL语法检查。
使用以下代码创建文件test.pc:
EXEC SQL SELECT * FROM DUAL WERE 1 = 1;
安装预编译工具后运行此命令:
proc INAME = test SQLCHECK = SYNTAX
您将看到此输出:
第1行第34列语法test.pc中的语法错误:
文件test.pc中第1行第34行的错误
EXEC SQL SELECT * FROM DUAL WERE 1 = 1;
................................. 1个
PCC-S-02201,在遇到以下情况之一时遇到符号“1”:
; ,for,union,connect,group,having,intersect,minus,
订单,开始,在哪里,用,
符号“有”代替“1”继续。
将它集成到您的解决方案中应该很简单。
请注意,它还可以执行在线语义检查,验证所有使用的过程和表在特定模式中是否有效。为此,您传入SQLCHECK = SEMANTICS USERID = youruser