• 締切済み

do - while文

こんにちは、tomokooです。 下記の様にソースを書きました。 rsはResultSetです。 ---------------------------- while(条件A){   処理; rs.next(); } while(rs.next()){   処理; } ---------------------------- うまくプログラムは動いたのですが 結果を見て1行飛ばされることに気づきました。 だから ---------------------------- while(条件A){   処理; rs.next(); } do{   処理; }while(rs.next()}; ---------------------------- としたところ、処理の中の rs.getString(i); //iは初期化済み で落ちてしまいます。 whileでよくてdo-whileでだめなことってあるんですか? 結構困ってます。 ご存知の方はよろしくお願いします。

みんなの回答

  • hameggs
  • ベストアンサー率38% (8/21)
回答No.3

amajunさんのおっしゃる通りです。 識者の方々におこられるのを承知で簡単に言うと・・・・ 1:データベースのカーソルは最初は一番最初の行の真上にいる。   ↓ 2:next()をおこなうと、カーソルが一つ下に移動する   ↓ 3:行が存在していればtureが返り、rsが値を取得できる って感じに考えてはどうでしょ(・w・? (あぅ、怒られそうだ・・・^^;)

noname#2102
質問者

お礼

みなさん、ありがとうございます。 問題解決しました! 問題は別のところにありました。。。 どこがいけなかったかというと、while(条件A)文の最後のデータαとdo文の最初のデータβは同じで、その同じ行同じ列のデータをそれぞれwhile(条件A)文とdo文でgetStringしてたんです! 同じ行の同じ列を2度getStringすると落ちるんですねー。 知らなかった。。。 そんなこんなでロジックを組みなおし、すっかり動くようになりました。 どうもお騒がせしました&ありがとうございました!

  • m_hagizo
  • ベストアンサー率65% (31/47)
回答No.2

do{   処理; } while(rs.next()); とした場合、rs.next()の評価を行う前に「処理」が実行されることに注意してください。つまり、最終レコードになったときに、最終レコードであることの判定が後に来てしまうために、rs.getString(i)で落ちている、ということです。 このロジックでこれを回避するためには、Statementを作るときに、「スクロール可能な」状態にしておく必要があるでしょう。修正すると、こんな感じです。 // スクロール可能なカーソルを作る Statement stmt = connection.createStatement( ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);  :  : while(条件A){   処理; rs.next(); } rs.beforeFirst(); // カーソルを先頭行の手前に移動する while(rs.next()){   処理; }

noname#30871
noname#30871
回答No.1

 do-whileでは、ループ中の処理を実行した後に条件判断されます。つまり、どんな条件であろうが処理は必ず1回は実行されます。だからループの最初の1回では「条件に合わないが処理してしまう」ことがありえます。  また、ResultSetの初期状態では、どのレコードも指していません。この状態でrs.getString()すると例外になります。rs.next()を実行して(trueが返れば)初めて1番目のレコードを指すようになり、getString()できるようになります。  以上から、do-whileの中のrs.getString()で例外が起こり得ます。  というわけで、すなおに while(rs.next()) {  処理 } と書くのがよいです。条件Aが絡むのであれば // 条件Aが満たされなければ、以降のレコードは無視する while(条件A && rs.next()) {  処理 } または // 条件Aを満たすレコードだけを拾う while(rs.next()) {  if(条件A) {   処理  } } となるでしょう。

参考URL:
http://www.javadrive.jp/servlet/jdbc/sql/index1.html

関連するQ&A