2011-12-12 52 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对象传递给递归调用。