首页 > 解决方案 > JDBC 根据另一个 select 语句的结果执行 select 语句

问题描述

我正在尝试编写一个 java 程序,该程序需要遍历“旧值”列表以从 oracle 数据库表中获取“新值”列表。OLD 值列表,我想从 shell 脚本传递这个列表,该脚本将是 java 程序的包装器。

a b c

--select 语句类似于

select new_name from items where old_name = ? //loop through the list of old values

第二步是使用上面查询中的 new_name 在下面的 select 语句中使用

select msgid from new_name 

我正在尝试做这样的事情-

Connection conn = DriverManager.getConnection
     ("jdbc:oracle:thin:@//host:port/SID", "userid", "password");

Statement stmt = conn.createStatement();

for (int i=0; i < arg.length; i++)
{
ResultSet getNewVal = stmt.executeQuery("select new_name from items where old_name = " + old_name[i]);

while (getNewVal.next()){

          String newVal = getNewVal.getString(1);
          ResultSet getMsgID = stmt.executeQuery("select msgid from " + newVal );
          System.out.println (getMsgID.getString(1));

}
}

问题 - 第一个查询的 ResultSet 关闭并在我执行第二个查询时生成异常(关闭的结果集:下一个)

有什么建议吗?

根据要求,包括示例表定义。

create table items ( new_name varchar2(20),old_name  varchar2(20) );
create table new_name ( msgid varchar2(20));

标签: javaoraclejdbc

解决方案


您正在尝试使用相同的Statememt对象来执行数据库查询。如果您重新使用相同的stmtobj 来执行另一个查询,它将关闭旧的ResultSet上下文并且您将得到相同的错误/异常。

默认情况下,每个 Statement 对象只能同时打开一个 ResultSet 对象。因此,如果一个 ResultSet 对象的读取与另一个 ResultSet 对象的读取交错,则每个对象都必须由不同的 Statement 对象生成。Statement 接口中的所有执行方法都会隐式关闭语句的当前 ResultSet 对象(如果存在打开的对象)。

阅读本文以获取更多信息...

虽然这可以通过多种方式解决,但我指出了两个不需要太多更改的简单解决方案。

  1. 使用另一个Statement对象在现有的ResultSet.

    Statement stmt = conn.createStatement();
    Statement nestedStmt = conn.createStatement(); // add this line       
    
    .
    .
    .
    ResultSet getMsgID = nestedStmt.executeQuery("select msgid from " + newVal ); // Change this line in while loop
    .
    .
    .
    
  2. 使用临时List或任何合适的集合来临时保存数据,但是如果 resultSet 中的结果太大,这可能会降低性能(我需要更多的 RAM 消耗)

去做这个,

创建一个简单的List<String>并将 的每个元素添加ResultSet到此列表中,然后遍历此新创建的列表(不是 on ResultSet),然后无需使用不同的Statement对象。

我希望这会有所帮助。


推荐阅读