選択の結果に基づく更新クエリがあり、通常は 1000 行を超えます。
これらの行の一部が、この更新によって更新される前に他のクエリによって更新された場合、レコードに問題が発生する可能性がありますか? たとえば、元のクエリと同期しなくなる可能性はありますか?
もしそうなら、バッチではなく個々の行を選択して更新する方が良いでしょうか?
違いがある場合、クエリは Microsoft SQL Server 2008 R2 で実行されています。
ありがとう。
選択の結果に基づく更新クエリがあり、通常は 1000 行を超えます。
これらの行の一部が、この更新によって更新される前に他のクエリによって更新された場合、レコードに問題が発生する可能性がありますか? たとえば、元のクエリと同期しなくなる可能性はありますか?
もしそうなら、バッチではなく個々の行を選択して更新する方が良いでしょうか?
違いがある場合、クエリは Microsoft SQL Server 2008 R2 で実行されています。
ありがとう。
いいえ。
他の何かが更新中の場合、テーブルを更新することはできません。
データベースは同時実行制御を使用し、ACID プロパティを使用して、まさにこの種の問題を防ぎます。
分離レベルについて読むことをお勧めします。SQL Server のデフォルトは ですREAD COMMITTED
。これは、他のトランザクションが、特定のトランザクションによって更新されたがコミットされていないデータを読み取ることができないことを意味します。
これは、select/update ステートメントによって返されるデータが、その時点でのデータベースを正確に反映していることを意味します。
データベースを変更するとREAD UNCOMMITTED
、選択/更新からのデータが同期されない状況に陥る可能性があります。
最初に選択してから更新する場合は、トランザクションを使用できます
BEGIN TRAN
-- your select WITHOUT LOCKING HINT
-- your update based upon select
COMMIT TRAN
ただし、選択から直接更新する場合は、心配する必要はありません。単一のトランザクションが暗示されます。
UPDATE mytable
SET value = mot.value
FROM myOtherTable mot
しかし...次のことはしないでください。そうしないと、デッドロックが発生します
UPDATE mytable
SET value = mot.value
FROM myOtherTable mot WITH (NOLOCK)