【问题标题】:How can I check SQL syntax for a JDBC statement without running the actual query?如何在不运行实际查询的情况下检查 JDBC 语句的 SQL 语法?
【发布时间】:2012-05-02 02:10:48
【问题描述】:

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

我想在不运行语句(通过 JDBC)的情况下检查语法是否有效,例如在“检查语句”按钮后面。是否有独立于供应商的方式来做到这一点?我的第一个想法是将查询简单地定义为 PreparedStatement 似乎不会导致任何类型的编译或错误检查。

【问题讨论】:

标签: sql oracle jdbc syntax verification


【解决方案1】:

可能为该语句发布解释计划会给您带来有用的结果。

另一个想法 - 但可能更难的是编辑要添加的查询(和 rownum

【讨论】:

  • 解释计划是要走的路。它将给出与“运行”查询相同的语法错误
  • 绑定参数如何处理?
  • 没错,如果您的查询中只有一个参数,这根本行不通。
  • 您可能会考虑用假值替换绑定 - 它是否会返回行无关紧要,只要它会解析即可。
【解决方案2】:

如果您正在处理 SELECT 查询,也许 JDBC PreparedStatement#getMetaData 可以工作?

【讨论】:

    【解决方案3】:

    这更像是一个 hack,而不是真正的答案,但您可以运行一个始终返回一行和一列的查询:

    SELECT ( EXISTS (SELECT 1 FROM dual)
             OR
             EXISTS (your Query here)
           ) AS result
    FROM dual 
    

    如果您的查询有效,则应返回 TRUE,如果无效则引发错误。

    【讨论】:

    • gordy 的评论得到了我的投票,因为它适用于 Oracle 以外的其他 dbms。
    • @user1938185 是的,FROM dual 仅适用于 Oracle 和 MySQL(我认为是 SQLite)。在其他方面,例如 SQL Server 和 Postgres,您可以完全删除 FROM dual,它也可以正常工作。
    【解决方案4】:

    您可以使用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;
    /
    

    【讨论】:

      【解决方案5】:

      您可以使用Oracle's Pro*C precompiler 执行语法检查 (download here)。

      这是一个用于预编译包含原始 Oracle SQL 语句的 C 代码的工具,但您可以“滥用”它来执行 SQL 语法检查。

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

        执行 SQL SELECT * FROM DUAL WERE 1=1;

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

        proc INAME=test SQLCHECK=SYNTAX

      3. 你会看到这个输出:

        文件 test.pc 第 1 行第 34 列的语法错误: 文件 test.pc 中第 1 行第 34 列出错
        执行 SQL SELECT * FROM DUAL WERE 1=1;
        ..................................1
        PCC-S-02201,在预期以下情况之一时遇到符号“1”:
        ; , 为, 联合, 连接, 分组, 有, 相交, 减号, 顺序,开始,在哪里,与,
        符号“有”被替换为“1”以继续。

      将其集成到您的解决方案中应该很简单。

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

      【讨论】:

        猜你喜欢
        • 2010-09-17
        • 1970-01-01
        • 2012-09-02
        • 2016-04-18
        • 2011-04-18
        • 2010-09-15
        • 2010-09-08
        • 2012-01-06
        相关资源
        最近更新 更多