2009-11-19 6 views
0

Я составляю список переменных страницы (который имеет список книг в нем) из работающей базы данных MYSQL. При попытке второй итерации в цикле while (rs.next()) я получаю SQL Exception, говоря, что ResultSet уже закрыт. Я нигде не вижу, чтобы этот код закрывал объект rs.ResultSet преждевременное закрытие

try { 
    stmt = con.createStatement(); 
    ResultSet rs = 
      stmt.executeQuery("SELECT pageURL," + 
        "pageName FROM pages GROUP BY pageName;"); 
    ResultSet rs2; 
    while(rs.next()) { // Where the error occurs on the second pass 
     Page tempP = new Page(rs.getString(1),rs.getString(2)); 
     rs2 = stmt.executeQuery("SELECT `books`.`itemID`,cost," + 
       "title,author,shortD,longD FROM " + 
       "books INNER JOIN pages ON " + 
       "books.itemID=pages.itemID WHERE " + 
       "pageName='" + rs.getString(2) + "';"); 
     while(rs2.next()) { 
      tempP.addBook(new Book(rs2.getInt(1), 
        rs2.getFloat(2),rs2.getString(3), 
        rs2.getString(4),rs2.getString(5), 
        rs2.getString(6))); 
     } 
     pages.addPage(tempP); 
    } 
} catch(SQLException e) { 
    System.err.print("SQLException: "); 
    System.err.println(e.getMessage()); 
} 

Вот содержимое таблицы страниц:

|pageName |pageURL |itemID| 
------------------------------- 
|Tech Books|./techbooks|1  | 
------------------------------- 
|Tech Books|./techbooks|2  | 
------------------------------- 
|Kids Books|./kidsbooks|3  | 
------------------------------- 
|Kids Books|./kidsbooks|4  | 
------------------------------- 
|Kids Books|./kidsbooks|5  | 
------------------------------- 

EDIT:

Хорошо, похоже, что ResultSet становится недействительным, когда я снова использовать заявление. Есть ли у кого-нибудь предложения по исправлению этой ситуации?

+3

Ваш второй запрос имеет возможную угрозу SQL-инъекции. Даже если вы уверены, что это безопасно, это плохая форма, чтобы кодировать этот путь, и это также повредит оптимизации ваших запросов в базе данных. –

+0

Я уверен, что это безопасно, но что бы вы предложили оптимизировать это? –

+1

@Kevin: используйте PreparedStatement со связанными переменными (setString) – Thilo

ответ

4

Процитируем Javadocs для заявления:

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

Создайте два утверждения или еще лучше используйте PreparedStatements со связанными переменными.

+0

Спасибо, кучка Пол! –

0

Смотрите документацию ResultSet:

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

Смежные вопросы