2012-03-02 15 views
4

我有一個關於在Java和遞歸中的對象ResultSet的問題。使用遞歸時ResultSet重置

我正在研究大學的一些代碼,每當我發現我用這個新節點遞歸的後代,但是當我退出遞歸併嘗試rs.next()指針已經從指向第1行回到第0行,當它到達第0行時,rs.next()失敗並返回!我知道那裏有一件事它還沒有讀過!這是什麼原因造成的?

我得到這個問題的唯一方法是通過結果集並獲取每個元素並將其添加到數組列表中,然後循環通過ArrayList對數組中的每個元素進行遞歸!這肯定是一個更好的解決方法嗎?

這是我使用

private Vector<String> getDescendents(String dogname, Vector<String> anc) { 
    if (anc == null) anc = new Vector<String>(); 
    ArrayList<String> tempList = new ArrayList<String>(2); 
    try { 
     System.out.println("Inside "); 
     childStmt.setString(1,dogname); 
     childStmt.setString(2,dogname); 
     ResultSet rs = childStmt.executeQuery(); 
     System.out.println("Before while "+rs.getRow()); 
     while (rs.next()){ 
      String col1 = rs.getString(1); 
      tempList.add(col1); 
      anc.add(col1); 
     } 
     for (String s:tempList){ 
      getDescendents(s,anc); 
     } 

    } 
    catch(Exception e) { 
     doError(e, "Failed to execute ancestor query in getBreeding"); 
    } 
    return anc; 
} 

然而在此之前,我有while循環內的getDescendents電話,因此沒有for循環,沒有任何ArrayList的新代碼,但每當它實際上遞歸它會當它返回遞歸時,結果集的鬆散跟蹤。

更多詳細信息: 當我使用調試器(幾乎所說的gdb那裏大聲笑太多C)結果集的ID是相同的,但行指針已返回到0和rs.next調用失敗!

再一次感謝任何解釋!

P.S它前面看起來像

private Vector<String> getDescendents(String dogname, Vector<String> anc) { 
    if (anc == null) anc = new Vector<String>(); 
    ArrayList<String> tempList = new ArrayList<String>(2); 
    try { 
     System.out.println("Inside "); 
     childStmt.setString(1,dogname); 
     childStmt.setString(2,dogname); 
     ResultSet rs = childStmt.executeQuery(); 
     System.out.println("Before while "+rs.getRow()); 
     while (rs.next()){ 
      String col1 = rs.getString(1); 
      anc.add(col1); 
      getDescendendts(col1,anc); 
     } 

    } 
    catch(Exception e) { 
     doError(e, "Failed to execute ancestor query in getBreeding"); 
    } 
    return anc; 
} 
+0

以前的代碼是什麼樣的? – 2012-03-02 19:40:11

+0

由於沒有tail調用優化,Java中的遞歸通常是一個壞主意。在打開結果集的過程中進行遞歸是一個糟糕的主意。 – 2012-03-02 19:41:12

+0

是的,我同意我討厭遞歸,但任務需要它:P它像樹遍歷這樣的事情是非常類似於,@ nicholas.hauschild編輯底部 – andrewktmeikle 2012-03-02 19:46:57

回答

12

它看起來就像你重新使用childStmt;不要這樣做。從Statement javadoc

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

你必須要麼先保存所有行,然後做遞歸查詢,或創建爲要提取每個ResultSetStatement

+0

+1。你用5秒打我:-) – 2012-03-02 19:41:50

+0

那是因爲當我執行一個語句時,它類似於打開一個到數據庫的新連接,所以當我再次調用childstmt時,它重新打開連接,我鬆開了前面的語句? Jeez讀到javadoc使得遞歸聽起來像一個可怕的主意!謝謝,非常appreicated! – andrewktmeikle 2012-03-02 19:45:27

+0

這可能是由於設計決定讓'Statement'簡單。每個Statement處理多個ResultSet會帶來更多的複雜性,所以他們假設如果你要重複使用一個語句,你已經完成了以前的數據。在非侵權案件中,這可能是真的。 – beerbajay 2012-03-02 19:51:11