2011-08-08 119 views
5

我正在使用SELECT语句从表中获取数据,然后将其插入到另一个表中。不过行“stmt.executeQuery(query);”插入表中的第一行然后退出。当我将这一行注释掉时,while循环遍历所有将它们打印出来的行。堆栈跟踪没有显示任何错误。这是为什么发生?为什么While(rs.next())语句在第一次迭代后结束?

try{     
    String query = "SELECT * FROM "+schema_name+"."+table; 

    rs = stmt.executeQuery(query); 

    while (rs.next()) { 

     String bundle = rs.getString("BUNDLE"); 
     String project_cd = rs.getString("PROJECT_CD"); 
     String dropper = rs.getString("DROPPER"); 
     String week = rs.getString("WEEK"); 
     String drop_dt = rs.getString("DROP_DT").replace(" 00:00:00.0",""); 

     query = "INSERT INTO INDUCTION_INFO (BUNDLE, PROJECT_CD, DROPPER, WEEK, DROP_DT) " 
       + "VALUES (" 
       + bundle+"," 
       + "'"+project_cd+"'," 
       + dropper+"," 
       + week+"," 
       + "to_date('"+drop_dt+"','YYYY-MM-DD'))"; 

     System.out.println(query); 

     stmt.executeQuery(query); 
    } 
}catch(Exception e){ 
    e.printStackTrace(); 
} 
+0

嗯......实际上我不知道在语句中调用'executeUpdate()'是否会关闭语句前面的'ResultSet'。而我现在懒得去测试它...... –

+1

已经回答了具体的问题,但作为一种观察:您应该使用准备好的语句并每次更改绑定变量,而不是使用值构建新的插入硬编码英寸(这似乎是一个不太可能的地方获得SQL注入,但取决于谁可以将条目放在源表中.​​..)。但是,为什么不用一个select-as-insert来实现,而不是循环呢? –

回答

24

你是被用来在你的循环的最后一行产生rsStatement重新使用。

这将关闭ResultSetrs。作为stated in the documentation

时生成它的Statement对象被关闭时,重新执行,或用于检索从多个结果序列中的下一结果的ResultSet对象将自动关闭。

您需要使用第二个Statement对象来执行INSERT语句。

9

Statement对象一次只能执行一件事,因此当您执行INSERT时,会使其生成的ResultSet无效。您需要创建第二个Statement对象才能执行INSERT

来自Statement documentation:“默认情况下,每个Statement对象只能同时打开一个ResultSet对象。因此,如果一个ResultSet对象的读取与另一个ResultSet对象的读取交错,则每个对象必须由不同的Statement对象,如果存在一个开放的对象,那么Statement接口中的所有执行方法隐式关闭一个statment的当前ResultSet对象。“

1

如果使用相同的语句,则会使先前的结果集无效。您应该使用不同的语句来执行更新/插入。

1

这是从接口Statement的Java文档:

默认情况下,每个Statement对象只有一个ResultSet对象可以是开放 在同一时间。

所以你最好使用第二个Statement或更好的PreparedStatement

而要执行INSERT SQL语句,您应该使用executeUpdate()而不是executeQuery()

相关问题