QA@IT

Read()すると中身が消える?

573 PV

以下のように処理を行っていたのですが、なぜかデータベースの内容が取得できなくなり、困っています。

発生した処理と現象は以下の通りです。デバックで中を見ると...
1行目でデータベースの値はdbReaderに入っている。
3行目でdbReaderの中を見るとなぜかきえている。
(評価中に発生した問題のため、この項目の値は古くなりました~)

1 using (DbDataReader dbReader = dbComm.ExecuteReader())
2 {
3 while (dbReader.Read())
4 {
5 //ここにdbReader[0]を使用した処理
6 }
7 }

  • 質問に書いてないとことが問題を起こしているのでその情報では何も分かりません。想像もできないです。 -
  • 先週は動作&値を取れていたソースの為、何を書けばよいのかもわからないのです・・・
    今週動かしたら値が取得できない事に気づき、調査した所、上記のような現象が発覚…
    -
  • 先週修正をいれた影響かと思い、修正を入れる前のソース&データベースのバックアップを戻してデバックモードでみても、値は取得できるが3行目で値が消滅する、という現象が発生… -
  • じゃあ、アプリではなく DB の内容に問題があるのでは? とにかく、アプリの問題か DB 側の問題かをまず切り分けてください。あと、ひどく情報不足だということを認識してますか? DB サーバーが何かさえ書いてないのですよ。1 行目、3 行目って何のことですか?
    -

回答

3行目で〜とありますが、デバッガで そのReadメソッドを再評価した場合、多分DBカーソルが進んでしまいますので、状態が変わり「評価中に発生した問題のため、この項目の値は古くなりました〜」となっているんじゃないでしょうか。

ウォッチ変数にもReadがいないように注意してください。
読み取り前にレコードが1件以上あるかどうかはdbReader.HasRowsプロパティで確認してください。

特に目的の結果が1件しかない場合はその評価とwhileによる実際の呼び出しで結局whileに入らないということも考えられます。

根本の問題としては実際に条件にあうデータがなくなったんじゃないでしょうか(接続先違うとか週次バッチでなにか消えたとか)。先週動いたはなんの保証にもならないです(10月しか動かないコードだったとか年月日の日が1桁になったからとか)。
それを確認する意味でも、最初のRead()の前にHasRowsを確認したほうがいいでしょう。falseならコマンドで実施しているものと同じ条件で(SQLを直接指定しているならdbCommのCommandTextを見てそれを使うといいでしょう)SQLを叩いてみて取得できるかどうか確認してください。

編集 履歴 (0)
  • 本件自己解決しました。
    今まで動いていたという事、クリーンしていなかった為に何故か本来エラーとなるものが動いてしまっていたようでした。(クリーンをしたらエラーが出て、ソースを直したら動きました…)
    WHILE文に注目していた事自体が誤りであり、Flied_ONIONさんが書いてくれたような動きをしているだけでした。
    その為、Flied_ONIONさんの解凍をベストアンサーとさせて頂きます
    -

どんな言語でどんなDBに接続しているかわかりませんが、dbReader.Read()の.Read()というメソットは、最初の1レコード目を読み込んで、中身の値を返すんじゃないかなと思います。
試しに、Record = dbReader.Read() としてみたら、Recordの中身に1レコード目の値が入ってないでしょうか?

whileで回すとしたら、こんな書き方はいかがでしょうか。

while (1)
{
  r = dbReader.Read()
  //ここにrを使った処理

  if(r == null){
    break;//rの中身が空になったらwhileループから抜ける
  }
}
編集 履歴 (0)
  • 違います。DbDataReader.Read メソッドが返すのは bool 型です。 質問者さんのコードの while (dbReader.Read()) は完全に正しいです。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。