2012-03-02 1 views
4

Javaおよび再帰でResultSetオブジェクトに関する質問があります。再帰を使用するとResultSetがリセットされる

私は大学のコードに取り組んでいました。子孫が見つかったときには、その新しいノードで再帰しましたが、再帰から出てrs.next()を試してみると、ポインタは1行目行0に戻り、行0に達したときにrs.next()が失敗し、それが返されました。そこにまだ読んでいなかったものが1つあることは分かっていました。これを引き起こす原因は何ですか?

この問題を解決する唯一の方法は、結果セットを調べてすべての要素を取得して配列リストに追加し、配列内の各要素の再帰を行うarraylistをループすることでした。確かに、これはこれの周りのより良い方法でなければならない?

これはでしょうしかし、この前に、私はwhileループ内getDescendents電話を持っていたので、どちらかのループなしの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; 
} 

を使用している新しいコードであります再帰から戻ったときの結果セットの緩やかなトラック。

詳細: 私はデバッガを使用していましたが(gdbとほとんど同じですが、Cではあまりにも多すぎます)、結果セットのIDは同じでしたが、行ポインタは0に戻り、rs.next呼び出しは失敗しました!

ここでも説明はありがたいです! ;それは以前にあなたがchildStmtを再利用しているように見えます

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

前のコードはどのように見えましたか? –

+0

Javaでの再帰は、通常、テールコールの最適化がないために悪い考えです。結果セットを開く途中の再帰はひどい考えです。 –

+0

ええ、私は再帰が嫌いだが、タスクはそれを必要とすることに同意する:P子孫を転覆させるツリートラバーサルなどのものは、@ nicholas.hauschildと非常によく似ている。 – andrewktmeikle

答えて

12

のように見えた

p.sこれをしないでください。 Statement javadocから:

デフォルトでは、Statementオブジェクトごとに1つのだけのResultSetオブジェクトを同時に 開くことができます。したがって、1つのResultSetオブジェクトの読み取り値が で、別のResultSetオブジェクトの読み取り値とインターリーブされている場合は、異なるStatementオブジェクトによってそれぞれ が生成されている必要があります。 Statement インタフェース内のすべての実行メソッドは、 が存在する場合、そのStatementの現在のResultSetオブジェクトを暗黙的に閉じます。

あなたは再帰クエリを行う、またはあなたが取得したい各ResultSetのための新しいStatementを作成し、その後、最初にすべての行を保存するためのいずれかがあります。

+0

+1で編集した。あなたは5秒で私を打ち負かしました:-) –

+0

私はステートメントを実行するときにデータベースとの新しい接続を開くのと同じように、childstmtを再度呼び出すときに接続を再開し、前のステートメントの内容を失ってしまいます。 Jeezがjavadocを読んでいると、再帰音がひどいアイデアのように聞こえるようになります!ありがとう、多くのappreicated! – andrewktmeikle

+0

これはおそらく、 'Statement'を単純にするという設計上の決定によるものです。'Statement'ごとに複数の' ResultSet'を扱うと複雑さが増すため、文を再利用しようとすると前のデータで済んでいると仮定します。非再帰的な場合、これはおそらく真実です。 – beerbajay

関連する問題