Получение java.sql.SQLException: операция не разрешена после закрытия ResultSet - PullRequest
19 голосов
/ 30 апреля 2011

Когда я выполняю следующий код, я получаю исключение.Я думаю, это потому, что я готовлю новое заявление с тем же объектом связи.Как мне переписать это, чтобы я мог создать подготовленное утверждение и начать использовать 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

Ответы [ 2 ]

28 голосов
/ 30 апреля 2011

Проблема в том, как вы извлекаете данные в getStuff().Каждый раз, когда вы посещаете getStuff(), вы получаете новый ResultSet, но не закрываете его.

Это нарушает ожидания класса Statement (см. Здесь - http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html):

По умолчанию только один объект ResultSet на объект Statement может быть открыт одновременно.Поэтому, если чтение одного объекта ResultSet чередуется с чтением другого, каждый из них должен быть сгенерирован различными объектами Statement.Все методы выполнения в интерфейсе Statement неявно закрывают текущий объект ResultSet статута, если существует открытый.

Что еще хуже, это rs из вызывающего кода. Он также выводится из поля statement, но не закрывается.

Итог: у вас естьнесколько ResultSet, относящихся к одному и тому же Statement объекту, одновременно открытому.

9 голосов
/ 30 апреля 2011

Объект ResultSet автоматически закрывается, когда объект Statement, который генерируется закрыто, перезапущено, или используется для получения следующего результата из последовательности нескольких результатов.

Я думаю, после while(rs2.next()) вы пытаетесь получить доступ к чему-то из rs1. Но он уже закрыт, так как вы повторно выполнили оператор, чтобы получить из него rs2. Так как вы не закрыли его, я полагаю, что он снова используется ниже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...