在ResultSet.execute之后循环终止

时间:2017-01-08 20:30:08

标签: java oracle jdbc while-loop executequery

我试图通过基于表COMPA的表COMPB上的Update和Delete操作使TABLE COMPB等效于TABLE COMPA。代码在生成适当的SQL时工作得很好。问题是,我将execute语句设置如下,while循环在第一次迭代中终止。无法理解java中ResultSet的这种行为。这里有什么帮助?我哪里错了?

//Comparision between Minus Table(seta) and COMPB (setc)
        //ID Contains Primary Key of COMPB Table
        ResultSet seta=stmt.executeQuery("select * from COMPA minus select * from COMPB");


        while(seta.next())
        { 
            String insert="";
            String update="";
            boolean contains=ArrayUtils.contains(ID, seta.getInt(1));

            if (contains==true)
             { 
                update="Update COMPB SET COMPB.EMPNAME='"+seta.getString(2)+"',COMPB.EMAILID='"+seta.getString(3)+"' where "+seta.getInt(1)+"=COMPB.EMPID";
                stmt.executeUpdate(update);
                System.out.println(update);
             }
            else 
             {
            insert="Insert INTO COMPB values ("+seta.getInt(1)+" , '"+seta.getString(2)+"' , '"+seta.getString(3)+"')";
              stmt.executeUpdate(insert);
              System.out.println(insert);
             }  


        }

3 个答案:

答案 0 :(得分:1)

可能有两个可能的原因:

  • 重用相同的stmt对象:结果集对象被映射到返回它的语句(通过executeQuery方法),并且在迭代过程中重新使用相同的语句对象将使结果集无效。您应该创建一个新的语句对象并使用它执行这些查询。
  • 使用CONCUR_READ_ONLY resultSet(默认):Here's Oracle有关结果集的文档。默认情况下,它不可修改。如果需要修改记录,则可能需要使用CONCUR_UPDATABLE结果集。 Here就是一个例子。

答案 1 :(得分:1)

  

无法理解java中ResultSet的这种行为。

您使用相同的PreparedStatement stmt实例执行更新:

ResultSet seta=stmt.executeQuery("select * from COMPA minus select * from COMPB");

while(seta.next()){ 
    ...

   update="Update COMPB SET COMPB.EMPNAME='"+seta.getString(2)+"',COMPB.EMAILID='"+seta.getString(3)+"'    where "+seta.getInt(1)+"=COMPB.EMPID";
   stmt.executeUpdate(update);
   System.out.println(update);
   ...
  }

您的ResultSet seta来自PreparedStatement stmt个实例 所以我想在PreparedStatement实例上调用另一个execute方法会对PreparedStatement实例返回的先前ResultSet对象产生副作用。

您应该创建PreparedStatement的新实例来执行其他查询。

答案 2 :(得分:0)

根据下面的建议,我通过创建preparestatement对象来改变循环。

         while(seta.next())
        { 

            boolean contains=ArrayUtils.contains(ID, seta.getInt(1));

            if (contains==true)
             { 


                PreparedStatement update_stmt =con.prepareStatement("Update COMPB SET COMPB.EMPNAME=?,COMPB.EMAILID=? where COMPB.EMPID=?");
                update_stmt.setInt(3,seta.getInt(1));
                update_stmt.setString(1,seta.getString(2));
                update_stmt.setString(2,seta.getString(3));
                int k=update_stmt.executeUpdate();  
                System.out.println(k+" records updated");

             }
            else 
             {

            PreparedStatement insert_stmt =con.prepareStatement("insert into COMPB values(?,?,?)");
            insert_stmt.setInt(1,seta.getInt(1));
            insert_stmt.setString(2,seta.getString(2));
            insert_stmt.setString(3,seta.getString(3));
            int k=insert_stmt.executeUpdate();  
            System.out.println(k+" records inserted"); 

             }  


        }