2009-05-28 8 views
2

SqlDataReaderを使用する場合、ExecuteReaderステップで完全に決定された戻り値セットですか?また、読み込み中にソーステーブルに書き込むことで何を得ることができますか?ここでは非常に荒い擬似コードの例を示します。SqlDataReader - 結果セットはキャッシュされていますか?

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がリストの先頭(アダムス)から一番下(チーグラー)にぶつかる。私は、SqlDataReaderが無害であると仮定しました(ha!)。本当ですか?偽ですか?

答えて

4

これはあなたのtransaction isolation levelまたはその他のロックヒントに依存しますが、デフォルトでiircはSQL Serverのテーブルから読み込むとこれらのレコードをロックするため、投稿したコードはデッドロック(sc2が最終的にタイムアウトになります)あなたのリーダーが終了するまで、トランザクションログとnoneは書き込まれません。私は頭の上からどれが覚えているのか覚えていない。

+0

私の実際の実装は、わかりやすくうまく機能しました。テーブルがロックされないようにレコードを確実に更新しましたが、ソート順に影響するフィールドは変更しませんでした。 – SeaDrive

+0

2番目のように聞こえます。更新はトランザクションログに保存されます。それともあなたはどこか弱い隔離レベルを設定しています。 –

1

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

+0

私は別のデータベース接続を使用しました。 – SeaDrive

0

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

もちろん、私は「これは本当にどのように動作するのか」の観点から興味深い質問を見つけました。

0

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

私はあなたがこれについて尋ねなかったことを知っていますが、これも擬似コードであることを知っていますが、sc()、sdr()、sc2()

関連する問題