2

SqlDataReader を使用する場合、戻り値セットは ExecuteReader ステップによって完全に決定されますか? または、読み取り中にソース テーブルに書き込むことによって取得するものに影響を与えることができますか? これは非常に大まかな疑似コードの例です。

sc = new SqlCommand("select * from people order by last, first",db) ;
sdr = sc.ExecuteReader() ;

while (sdr.read())
{
    l = (string) sdr["last"] ;
    k = (string) sdr["key"] ;
    if (l.Equals("Adams")) 
    {
       sc2 = new SqlCommand("update people set last = @nm where key = @key") ;
       sc2.Parameters.Add(new SqlParameter("@nm", "Ziegler"));
       sc2.Parameters.Add(new SqlParameter("@key", k));
       sc2.ExecuteNonQuery() ;
    }
}

読んでいるテーブルへの書き込みが原因で、他の環境で多くの悪いエラーが発生するのを見てきました。ここで、レコード k はリストの一番上 (Adams) から一番下 (Ziegler) にバンプされます。私は、SqlDataReader が免疫があると仮定しました (ha!)。真実?間違い?

4

4 に答える 4

4

トランザクションの分離レベルやその他のロックのヒントによって異なりますが、iirc はデフォルトで SQL Server のテーブルから読み取るとこれらのレコードがロックされるため、投稿したコードはデッドロック (sc2 は最終的にタイムアウト) するか、更新がトランザクション ログであり、リーダーが終了するまで何も書き込まれません。私は頭の上からどれを覚えていません。

于 2009-05-28T14:22:30.577 に答える
1

私が見る 1 つの問題は、リーダーが開いているときにデータベース接続を所有し、リーダーが開いている間は他に何も使用できないことです。したがって、これを行う唯一の方法は、別のデータベース接続を使用することですが、それでもトランザクション レベルに依存します。

于 2009-05-28T14:26:27.340 に答える
0

読み取ったデータがこれらの更新によって変更されていないと仮定したい場合は、データを一時オブジェクト コンテナーに読み取り、すべての読み取りが完了したら、更新を行うことができますか? それは問題を無意味にするでしょう。

もちろん、「これが実際にどのように機能するのか」という観点から、この質問は興味深いものでした。

于 2009-05-28T14:27:47.713 に答える
0

クエリ結果を繰り返し処理している間に更新を行いたい場合は、すべてを DataSet に読み込むことができます。

あなたがこれについて尋ねていないことは知っていますし、これが疑似コードであることも知っていますが、sc、sdr、および sc2 変数を using () ステートメントでラップして、それらが適切に破棄されるようにしてください。

于 2009-05-28T14:30:47.690 に答える