- PR -

ResultSetの使い方について

投稿者投稿内容
くり
常連さん
会議室デビュー日: 2006/10/30
投稿数: 28
お住まい・勤務地: tokyo
投稿日時: 2006-11-28 11:02
<%
ResultSet rs =null;

st = list.DbConnect.getStatement(); //データベース接続

rs = st.executeQuery("select * from t_team where DEL_FLG=0" );
while(rs.next()) {
id = rs.getString("TEAM_ID");

rs = st.executeQuery("select count(*) as MEMBER_ID from t_member where TEAM_ID ="+id);
while(rs.next()){
String num = rs.getString("MEMBER_ID");
System.out.println(num);
%>

<td><%= id %> </td> //t_team
<td><%= num %> </td> //t_member

}
}
変数idの数で、複数の別テーブルのカウントを出したいのですが
2回ResultSetを使いたいのですが、一度しか出力されず、次のカラムが出力されません。
この場合どうのようにすればよろしいでしょうか?
t_teamとt_memberのテーブルは共通性を持たしています。
t_teamの1のt_memberは15
t_teamの2のt_memberは20
といった、ものを出力したいのです。
よろしくお願いします。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2006-11-28 11:28
同じ変数に代入しているんだから、後で入れた値に変わってしまうでしょう?
コード:
ResultSet rs = st.executeQuery("省略"); // (1)
while(rs.next()) { // (2)
    rs = st.executeQuery("省略"); // (3) ← ここでrsの上書き
    while(rs.next()) { (4)
        // (5)
    }
    // (6)
}


(1)(2)(3)と流れて(4)(5)を繰り返して
(6)にきた時点でrs.next()はfalseを返すわけですよ。
(4)のwhileを抜けているんだから当然falseですよね。
そのrs.next()を外側2回目のループで(2)に来た時点でまた見るわけです。
さっきfalseだったのだから今回も当然falseとなるのでそのままループを抜けます。

値を確認しながらステップ実行でもすれば動きがわかりやすいかもしれませんね。
想馬
大ベテラン
会議室デビュー日: 2003/05/29
投稿数: 245
お住まい・勤務地: 神奈川・東京
投稿日時: 2006-11-28 11:28
引用:

くりさんの書き込み (2006-11-28 11:02) より:
rs = st.executeQuery("select * from t_team where DEL_FLG=0" );
while(rs.next()) {
id = rs.getString("TEAM_ID");

rs = st.executeQuery("select count(*) as MEMBER_ID from t_member where TEAM_ID ="+id);
while(rs.next()){


2重ループ処理なんだからResultSetオブジェクトを2つに分けて持つようにした方がいいのでは? このままだと1つ目のwhile内で実行した結果得られるResultSetオブジェクトで最初のwhileが終了するか判定していることになります。
_________________
己への戒め

「活動的な馬鹿より恐ろしいものはない」 by ゲーテ
くり
常連さん
会議室デビュー日: 2006/10/30
投稿数: 28
お住まい・勤務地: tokyo
投稿日時: 2006-11-28 11:51
nagiseさん、想馬さん返信ありがとうございます。

Rnagiseさん、esultSetが上書きされているのはわかるのですが、
この場合、カウントを複数出力するには、rs,next()
しかわからないのです。
詳しく解説ありがとうございます。
次からそのように質問します。


<<2重ループ処理なんだからResultSetオブジェクトを2つに分けて持つようにした方がいいのでは?
想馬さん、この場合、

<%
ResultSet rs =null;
ResultSet rst =null;

rst = st.executeQuery("select count(*) as MEMBER_ID from t_member where TEAM_ID ="+id);
while(rst.next()){
String num = rst.getString("MEMBER_ID");
System.out.println(num);
%>
といった形にすればよいのでしょうか?
想馬
大ベテラン
会議室デビュー日: 2003/05/29
投稿数: 245
お住まい・勤務地: 神奈川・東京
投稿日時: 2006-11-28 12:34
引用:

くりさんの書き込み (2006-11-28 11:51) より:
<<2重ループ処理なんだからResultSetオブジェクトを2つに分けて持つようにした方がいいのでは?
想馬さん、この場合、

<%
ResultSet rs =null;
ResultSet rst =null;

rst = st.executeQuery("select count(*) as MEMBER_ID from t_member where TEAM_ID ="+id);
while(rst.next()){
String num = rst.getString("MEMBER_ID");
System.out.println(num);
%>
といった形にすればよいのでしょうか?


2つに分けるのはその通りですが、どうせならwhile内のResultSetはその中で定義しましょう、そうすれば変数のスコープがはっきりして分かりやすくなるので上書きしてしまうといったバグが入りづらくなると思います。
コード:

// こんな感じで

ResultSet rs_t_team = st.executeQuery( "select * from t_team where DEL_FLG=0" );
while( rs_t_team.next() ) {
String id = rs_t_team.getString( "TEAM_ID" );
ResultSet rs_t_member = st.executeQuery("select count(*) as MEMBER_ID from t_member where TEAM_ID =" + id );

while( rs_t_member.next() ) {
String num = rs_t_member.getString( "MEMBER_ID" );
}

rs_t_member.close();
}
rs_t_team.close();


ループ内で使うのはPreparedStatementの方が良いかもしれません。

# ResultSetのclose処理を追記

[ メッセージ編集済み 編集者: 想馬 編集日時 2006-11-28 12:36 ]
るぱん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 1370
投稿日時: 2006-11-28 13:05
るぱんです。

ちょっとだけ脱線。
そもそも、タグが打てる所でDBタッチすべきなのかが疑問。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2006-11-28 13:14
引用:

るぱんさんの書き込み (2006-11-28 13:05) より:
ちょっとだけ脱線。
そもそも、タグが打てる所でDBタッチすべきなのかが疑問。



標準タグライブラリであるJSTLにもデータベースアクセス用の
タグが用意されているのをご存知ですか?
大規模開発ではJSPはMVCのViewに徹するべし、というのに賛成ですが、
PHPライクに小さなアプリを作るのであればJSPだけで完結させるのもよいと思います。
ケースバイケースだと思いますよ。

#もっともスクリプトレットでDBアクセスはやめたほうがいいと思う。
#try - catch - finallyでちゃんと後始末してるのかさえ心配。
くり
常連さん
会議室デビュー日: 2006/10/30
投稿数: 28
お住まい・勤務地: tokyo
投稿日時: 2006-11-28 15:06
書き込みありがとうございます。

finalyは使ってませんが
try{
if(rs != null){
rs.close();
}

if(st != null){
st.close();
}
if(conn != null){
conn.close();
}
}catch(SQLException e){}
を使用してます。

Operation not allowed after ResultSet closed、というエラーがですが、
ソースは想馬さんと同じにしたのですが、
ResultSetが閉じた後には認められない操作

ResultSet rs_t_team = st.executeQuery( "select * from t_team where DEL_FLG=0" ); @
while( rs_t_team.next() ) { A
String id = rs_t_team.getString( "TEAM_ID" );
ResultSet rs_t_member = st.executeQuery("select count(*) as MEMBER_ID from t_member where TEAM_ID =" + id );B

while( rs_t_member.next() ) { C
String num = rs_t_member.getString( "MEMBER_ID" );
}

rs_t_member.close();D
}
rs_t_team.close();E


スキルアップ/キャリアアップ(JOB@IT)