如何在不运行实际查询的情况下检查JDBC语句的SQL语法?

时间:2012-04-20 13:21:26

标签: sql oracle jdbc syntax verification

我有一个SQL语句(对于Oracle数据库)如果有效则需要很长时间才能运行。如果它无效,则立即返回错误。

我想检查语法是否有效而不运行语句(通过JDBC),例如在'check statement'按钮后面。是否有独立于供应商的方式?我首先想到的只是将查询定义为PreparedStatement似乎不会导致任何类型的编译或错误检查。

5 个答案:

答案 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语法检查。

  1. 使用以下代码创建文件test.pc:

    EXEC SQL SELECT * FROM DUAL WERE 1 = 1;

  2. 安装预编译工具后运行此命令:

    proc INAME = test SQLCHECK = SYNTAX

  3. 您将看到此输出:

    第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”继续。

  4. 将它集成到您​​的解决方案中应该很简单。

    请注意,它还可以执行在线语义检查,验证所有使用的过程和表在特定模式中是否有效。为此,您传入SQLCHECK = SEMANTICS USERID = youruser