Java JDBC Single Statement 对象在 while 循环之前和 while 循环内

Posted

技术标签:

【中文标题】Java JDBC Single Statement 对象在 while 循环之前和 while 循环内【英文标题】:Java JDBC Single Statement object before while loop and inside while loop 【发布时间】:2019-03-15 00:29:58 【问题描述】:

我正在编写一个使用 JDBC 连接到 Oracle 的核心 java 程序。

我正在选择带有选择条件的第一个表以获取少量行 ID。我在结果集中选择了一些记录 现在我在 while 循环中循环结果集 (while resultSet.next()) 然后为 id 与第一个结果集中的 id 相同的行选择我的第二个表

在两个选择中,我都使用相同的 Statement 对象。在运行程序时,我只获得第一行详细信息,然后 java 抛出结果集已关闭的错误

简而言之,我想知道是否可以在循环之前和循环内使用一个 Statement 对象?

下面是我的代码示例

allCOBbatchRSet=stmt.executeQuery("SELECT RECID FROM V_F_BATCH WHERE BATCH_STAGE IS NOT NULL");
while (allCOBbatchRSet.next())

        BatchRSet=stmt.executeQuery("SELECT XMLRECORD FROM F_BATCH WHERE RECID="+cobBatchRecId);
        BatchRSet.next();
        ............

异常失败

java.sql.SQLException: Closed Resultset: next at
oracle.jdbc.driver.InsensitiveScrollableResultSet.ensureOpen(InsensitiveScrollableResultSet.java:109) at
oracle.jdbc.driver.InsensitiveScrollableResultSet.next(InsensitiveScrollableResultSet.java:398) at
com.manohar.t24.COBDetails.getCOBDetails(COBDetails.java:46) 

【问题讨论】:

为什么是星号? 在问题中添加代码 sn-p 会给出一些观点,而不是你在做什么。 为什么在java中使这个逻辑复杂化..你不使用连接吗? 大家好,感谢您的帮助。我已经添加了我的代码部分。我正在使用相同的 Statement 对象来执行 2 个不同的 SQL Select 查询。我的 while 循环只执行一次,当循环处于第二次迭代时,它失败并出现异常 java.sql.SQLException: Closed Resultsset: next at oracle.jdbc.driver.InsensitiveScrollableResultSet.ensureOpen(InsensitiveScrollableResultSet.java:109) 在 oracle .jdbc.driver.InsensitiveScrollableResultSet.next(InsensitiveScrollableResultSet.java:398) at com.manohar.t24.COBDetails.getCOBDetails(COBDetails.java:46) 是的,您可以使用一个Statement,但是一旦您从中获得第二个ResultSet,第一个就会失效。 【参考方案1】:

在对由该语句创建的结果集进行迭代时,您不能重用该语句,因为在该 Statement 对象上执行另一个查询(或任何其他语句类型)将自动关闭前一个查询执行的结果集。这是 JDBC API 和规范所要求的。

如果你想这样做,那么你需要禁用自动提交*并使用两个语句对象。

但是,您显示的代码是一种称为 N+1 查询问题的反模式,通常您不应遍历结果集以执行每行的其他单独选择:您可以创建一个单独的选择语句来执行此操作为你。这通常表现得更好。

例如,您可以使用:

select V_F_BATCH.RECID, F_BATCH.XMLRECORD 
from V_F_BATCH
inner join F_BATCH
  on F_BATCH.RECID = V_F_BATCH.RECID
where V_F_BATCH.BATCH_STAGE is not NULL 

这也将避免您当前代码存在的潜在 SQL 注入问题。


*:禁用自动提交是必要的,因为 JDBC 需要执行任何语句才能在自动提交模式下提交。并且提交也会关闭打开的结果集,除非它们在提交时可以保持(尽管一些 JDBC 驱动程序在这方面是宽松的,结果集不会在自动提交边界上关闭)。

【讨论】:

以上是关于Java JDBC Single Statement 对象在 while 循环之前和 while 循环内的主要内容,如果未能解决你的问题,请参考以下文章

jdbc java数据库连接 3)Statement接口

8.JDBC

JDBC PreparedStatement Batch continue insert on error

使用JDBC向数据库中插入一条数据(第一次修改版)

JDBC编程示例

201621123065《JAVA程序设计》第14周