2009-11-19 92 views
0

我正在從正在運行的MYSQL數據庫編譯頁面變量列表(其中有書籍列表)。在while(rs.next())循環中嘗試第二次迭代時,我收到一個SQL異常,說明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  | 
------------------------------- 

編輯:

好吧,它看起來當我再次使用Statement這樣的ResultSet無效。有沒有人有任何建議來糾正這種情況?

+3

您的第二個查詢有可能的SQL注入威脅。即使你確定它是安全的,這種編碼方式也是不好的,它也會影響數據庫中查詢的優化。 – 2009-11-19 00:28:32

+0

我確定它是安全的,但是您會建議如何優化? – 2009-11-19 00:40:14

+1

@Kevin:使用帶有綁定變量的PreparedStatement(setString) – Thilo 2009-11-19 01:00:26

回答

4

引述的Javadoc聲明:

默認情況下,每個Statement對象只有一個ResultSet對象可以是在同一時間打開。因此,如果一個ResultSet對象的讀取與另一個ResultSet對象的讀取交錯,則每個對象必須由不同的Statement對象生成。 Statement接口中的所有執行方法隱式關閉一個語句的當前ResultSet對象(如果存在一個打開的對象)。

創建兩條語句,或更好地使用帶有綁定變量的PreparedStatements。

+0

感謝Paul! – 2009-11-19 00:36:28

0

ResultSet文檔:

時生成它的Statement對象被關閉時,重新執行,或用於檢索從多個結果的序列中的下一個結果一個結果對象被自動關閉。