0

SQLサーバーは、同じ単一の実行で同じ行を複数回更新して異なる結果になるのを防ぎますか?

1 つのテーブルに次のような行があるとします。

1
2
3

そして、すべての '1' を '2' に変更し、すべての '2' を '3' に変更するために 1 回の更新が実行されます。最初の行を '2' に変更し、次に再び '3' に変更して、すべての行を「3」の値?

以下を使用して SQL Server でテストします。

create table t ( c1 int );
insert into t (c1) values (1);
insert into t (c1) values (2);
insert into t (c1) values (3);

update t
set c1 = 
    case 
        when c1 = 1 then 2 
        when c1 = 2 then 3 
        else c1 
    end
;

select * 
from t;

結果は、値ごとに 1 つのロジック更新のみを示唆します。

しかし、この場合、すべての値が同じページにあると考えています (セットが小さいため)。ただし、それらが異なるページにあり、更新中に行をスキャンするために 1 つのインデックスが使用されている場合、実行の開始時に更新された値がインデックス内で別のページにプッシュされ、別のページに再度アクセスされる可能性があります。これと同じ実行。その場合、その行は数回更新され、異なる結果になる可能性があります。

私のテストではこの動作は示されませんが、これが SQL Server によって強制されているのか、またはそれを防ぐためにたまたま実行計画によってテストが機能しているのかはわかりません。

別の列に更新するか、他の手法を使用することでこれを防ぐことができます.SQL Serverを信頼してこの状況を防ぐことができるかどうかを尋ねています.

4

3 に答える 3

0

さらに調査した結果、SQL Server にはこの種の動作に対する保護があるようです。

この問題はよく知られており、「ハロウィン問題」という名前さえ付けられています。

この投稿では、SQL Server がこれを解決する方法について説明します。

したがって、プログラマーは、SQL Server がこれ (ハロウィン問題) を防ぐことを信頼できるはずです。追加の列や一時テーブルは必要ありません。

于 2013-06-24T18:20:19.947 に答える
0

この場合、データベースは完全に予測可能であると信頼できます。

データベースはcase式の結果で各レコードを更新するため、各レコードは 1 回だけ更新されます。

式をcase分割して、値に応じて更新するレコードを見つける複数ステップの更新にすることはありません。つまり、次のようにはなりません。

update t
set c1 = 2
where c1 = 1;
update t
set c1 = 3
where c1 = 2
于 2013-06-24T15:43:48.040 に答える