質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.99%

ExecuteReaderループ中の更新処理

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 4,940

Qoo

score 1061

以下のようにデータベースを取得し、条件に応じて1件ずつupdateをしたいのですが、
ExecuteNonQueryの部分でエラーになってしまいます。

ExecuteReaderループ中の更新処理を行う場合どうすればよいでしょうか。

MySqlCommand cmd;
MySqlCommand cmd2;
MySqlDataReader reader;

MySqlConnection con = new MySqlConnection();
con.ConnectionString = "server=xxx;user id=xxx;Password=xxx;persist security info=True;database=xxx";
con.Open();

DateTime dt = DateTime.Now;
cmd = new MySqlCommand("select uid from test ;", con);
reader = cmd.ExecuteReader();
while (reader.Read())
{
  //処理~

  cmd2 = new MySqlCommand("update test set flg=1 where uid='" + uid + "';"
  cmd2.ExecuteNonQuery();                //←エラー   
}

reader.Close();
cmd.Dispose();
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Kamata

    2016/10/01 10:00

    エラーの内容も書いておくと解答がつきやすいと思います。

    キャンセル

回答 1

checkベストアンサー

+1

cmd2 = new MySqlCommand の末尾に ,con); が付いてないようですが、これビルド出来てますか?
それ以上のことはエラーメッセージがないとわからないと分からないですね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/02 04:27

    conはコピペミスでした。
    エラー内容は下記でしたので、DataReader をCloseすると実行できたのですが、
    ループを終了してから(対象を全てアップロードしてから)closeするにはどうすればよいでしょうか

    There is already an open DataReader associated with this Connection which must be closed first.

    キャンセル

  • 2016/10/02 16:27

    そういえばDataReaderのオープン中は他のコマンドを実行できないという制限がありました。

    とすれば解決策は3つ。

    1つ目。
    DataReaderで読み込んだ値を一旦、Listクラスになどのコレクションに保存しておき、DataReaderのクローズ後にコレクションを使ってcmd2.ExecuteNonQueryを実行する。
    DataReaderの代わりにDataAdapterを使ってDataTableに読み込んでもよし。

    2つ目。
    SQL Server の場合、接続文字列に MultipleActiveResultSets=True を付加して、複数の結果セットの同時使用を可能にする。
    PostgresSQL の場合、接続文字列に Preload Reader=true を付加してDataReaderのプレロードを有効にする。
    ただし MySQL の接続文字列にそれらのオプションがあるかどうか分からない。ゴメン。

    3つ目。
    DataConnectionをもう1つ開き、cmd と cmd2 は別々のDataConnectionを使用する。

    まあ普通は1つ目の方法ですよね。
    3つ目の方法使ったら怒られるかバカにされますね。きっと。

    キャンセル

  • 2016/10/03 01:55

    無難に1つ目を選択しました。
    DataReaderをcloseした後、cmdをdisposeして開放した後、
    再度、cmdでnew MySqlCommandとすることで、cmd2も不要にすることができました。
    ありがとうございました。

    キャンセル

  • 2016/10/03 10:11

    解決したようで良かったです。

    cmd2 を削るのであれば、DataReaderをcloseした後、
    cmd.CommandText = "update test set flg=1 where uid='" + uid + "';"
    とすることで、cmd.dispose() と cmd = new MySqlCommand も要らなくなると思います。

    もっと言えば パラメーター も使用した方がパフォーマンスが良くなりますが、私は C# も MySql も詳しくないので説明は止めておきます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.99%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる