2011-12-12 53 views
0

我在我的數據庫中有一個表,它包含2列:uid1 - 某人的ID,uid2 - 他的朋友。使用postgresql的Java ResultSet

我想創建一個列表,我有人的朋友 - 直到5深度連接。

所以我建立了下面的遞歸方法:

private void recursive(int theUid,ResultSet rs,ArrayList<Integer> friends,int count,int next,PreparedStatement pstmt) throws SQLException{ 
     if(count>=1 && next==theUid){ 
      return; 
     } 
     else if(count>=DEPTH_OF_CONNECTION){ 
      return; 
     } 

     else{ 
      pstmt.setInt(1,next); 
      rs=pstmt.executeQuery(); 
      count++; 
      while(rs.next()) { 
       friends.add(rs.getInt(1)); 
       recursive(theUid,rs,friends,count,rs.getInt(1),pstmt); 
      } 
     } 
    } 
} 

而且我得到了以下錯誤:

Exception in thread "main" org.postgresql.util.PSQLException: This ResultSet is closed. at org.postgresql.jdbc2.AbstractJdbc2ResultSet.checkClosed(AbstractJdbc2ResultSet.java:2654) at org.postgresql.jdbc2.AbstractJdbc2ResultSet.next(AbstractJdbc2ResultSet.java:1786)

你能幫我找到是什麼問題?

+0

你知道你可以做到這一點在PostgreSQL的只是一個單一的聲明? –

+0

與服務器交談每一步都非常昂貴。一個帶有[遞歸CTE](http://www.postgresql.org/docs/9.1/static/queries-with.html)的單個查詢就是要走的路。 –

回答

9

Javadoc對於JDBC聲明說

By default, only one ResultSet object per Statement object can be open at the same time.

所以我的猜測是你試圖打開太多的結果集在同一時間同一個PreparedStatement的。

編輯:

Postgres jdbc driver doc似乎證實了它:

You can use a single Statement instance as many times as you want. You could create one as soon as you open the connection and use it for the connection's lifetime. But you have to remember that only one ResultSet can exist per Statement or PreparedStatement at a given time.

+1

只是爲了完成你的[正確]答案。代碼應該從結果集中取得所有朋友,關閉它,然後遞歸它所得到的列表。 – jorgeu

+0

...或使用[公共表格表達](http://www.postgresql.org/docs/9.0/static/queries-with.html):) – soulcheck

1

從我所知道的,你正在使用ResultSet對象來存儲你的語句結果,然後將它作爲參數傳遞給遞歸函數調用。所以基本上你會覆蓋變量並失去對它的引用。您應該編寫您的sql語句來檢索所需的數據,或者不要將相同的ResultSet對象傳遞給遞歸調用。