获取java.sql.SQLException: ResultSet关闭后不允许操作



当我执行下面的代码时,我得到一个异常。我认为这是因为我正在准备新的语句与相同的连接对象。我应该如何重写这个,以便我可以创建一个准备好的语句并使用rs2?我是否必须创建一个新的连接对象,即使连接到相同的数据库?

    try 
    {
        //Get some stuff
        String name = "";
        String sql = "SELECT `name` FROM `user` WHERE `id` = " + userId + " LIMIT 1;";
        ResultSet rs = statement.executeQuery(sql);
        if(rs.next())
        {
            name = rs.getString("name");
        }
        String sql2 = "SELECT `id` FROM  `profiles` WHERE `id` =" + profId + ";";
        ResultSet rs2 = statement.executeQuery(sql2);
        String updateSql = "INSERT INTO `blah`............"; 
        PreparedStatement pst = (PreparedStatement)connection.prepareStatement(updateSql);    
        while(rs2.next()) 
        { 
            int id = rs2.getInt("id");
            int stuff = getStuff(id);
            pst.setInt(1, stuff);
            pst.addBatch();
        }
        pst.executeBatch();
    } 
    catch (Exception e) 
    {
        e.printStackTrace();
    }
private int getStuff(int id)
{
    try
    {   
            String sql = "SELECT ......;";
            ResultSet rs = statement.executeQuery(sql);
            if(rs.next())
            {
                return rs.getInt("something");
            }
            return -1;
    }//code continues

问题在于您在getStuff()中获取数据的方式。每次你访问getStuff(),你获得一个新的ResultSet,但你不关闭它。

这违反了Statement类的期望(参见这里- http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html):

)

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

更糟糕的是调用代码中的rs。它也衍生自statement字段,但它不是封闭的。

底线:你有几个属于同一个Statement对象的ResultSet并发打开。

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

我猜在while(rs2.next())之后,你试图从rs1访问一些东西。但是它已经关闭了,因为你重新执行了语句,从中得到了rs2。因为你没有关闭它,我相信它在下面又使用了。

相关内容

  • 没有找到相关文章

最新更新