【问题标题】:Query runs on DB but throws exception in java查询在 DB 上运行,但在 java 中抛出异常
【发布时间】:2011-10-27 17:47:45
【问题描述】:

我在执行嵌套 sql 查询时遇到了一些问题。当我在 TOAD(对于 Oracle DB)上运行它时它工作正常,但是当我尝试从我的 java 程序执行相同的查询时,它给了我一个错误:ORA-00923:在预期的地方找不到 FROM 关键字: 这是查询:

Select *
from(select tb1.Number, tb1.Desc, tb1.Local, tb2.Division
     from tb1
     inner join tb2
     on tb1.Number = tb2.Number
     and Local in ('ENG_USA', 'ENG_CHINA', 'FR_FRENCH'))
where Number in ('7512','4706')

就像我提到的,它在 Toad 上执行良好并且能够检索数据,但相同的查询会引发 ORA-00923 异常。

rset = stmt.executeQuery(Select *
from(select tb1.Number, tb1.Desc, tb1.Local, tb2.Division
from tb1
inner join tb2
on tb1.Number = tb2.Number
and Local in ("+loc+"))
where Number in ("+s+")

回复报价

【问题讨论】:

    标签: java sql oracle jdbc nested-query


    【解决方案1】:

    我在 mysql 上遇到了类似的问题。我的问题是我将查询拆分为多行,而在 2 行之间没有留下空格。 所以你的查询应该是:

    rset = stmt.executeQuery("Select * from(select tb1.Number, tb1.Desc, tb1.Local, tb2.Division from tb1 inner join tb2 on tb1.Number = tb2.Number and Local in ("+loc+")) where Number in ("+s+")"
    

    PS:我想把这个写成评论,但由于某种原因我不能回答这个问题。对不起!

    【讨论】:

      【解决方案2】:

      首先,我在您的 Java 代码中看不到开头或结尾的双引号。由于您的 Java 代码必须编译才能接收到 Oracle 错误,我假设在 SELECT 之前有一个双引号,在最后一个关闭括号之后有一个双引号,然后是另一个关闭父级匹配executeQuery 上的开放括号。所以我假设你的实际代码类似于

      rset = stmt.executeQuery(
              "Select *
                 from(select tb1.Number, tb1.Desc, tb1.Local, tb2.Division
                        from tb1
                             inner join tb2
                                on tb1.Number = tb2.Number
                                   and Local in ("+loc+"))
                       where Number in ("+s+")");
      

      您是否有理由动态构建 SQL 语句而不是使用绑定变量?使用绑定变量更安全,因为您无需担心 SQL 注入攻击。它更有效,因为您不必每次都强制数据库硬解析查询。它使您免于引用和转义的各种错误。在您的情况下,假设局部变量 loc 没有前导单引号和尾随单引号,您需要将它们包含在查询中

      rset = stmt.executeQuery(
              "Select *
                 from(select tb1.Number, tb1.Desc, tb1.Local, tb2.Division
                        from tb1
                             inner join tb2
                                on tb1.Number = tb2.Number
                                   and Local in ('"+loc+"'))
                       where Number in ("+s+")");
      

      如果您使用绑定变量并将loc 绑定到第一个绑定变量,另一方面,您无需担心添加单引号(或转义loc 中的任何单引号。

      【讨论】:

      • 字符串 loc 已经附加了单引号,如下所示: String loc = "'ENG_USA','ENG_CHINA', 'FR_FRANCE'";至于双引号,我很抱歉这是一个错字。我的代码中有它们..所以这仍然会给我同样的错误。
      • @user973536 - 您能否在字符串变量中构建 SQL 语句,打印该变量,然后将该变量传递给 executeQuery 调用?您在构建 SQL 语句的某个时候引入了一个错误,但是如果不确切知道两个变量中的内容,就很难确定错误发生在哪里。当然,如果您使用绑定变量会更容易,因此您不必担心这些事情。
      • 我在一行中传递了查询并且它有效。所以我想把查询分成多行会有一些问题。感谢您的帮助。
      • 如果多行语句抛出错误,则几乎总是在行尾缺少空格的问题。如果你在最后的" 之前添加一个空白,你应该没问题:"SELECT col" + "FROM some_table" 将产生无效的 SQL。 "SELECT col " + "FROM some_table" 将创建有效的 SQL。如果您遵循该规则,多行语句不是问题。
      猜你喜欢
      • 2011-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多