というテーブル構造を想定しますMyTable(KEY, datafield1, datafield2...)
。
多くの場合、既存のレコードを更新したり、存在しない場合は新しいレコードを挿入したりする必要があります。
本質的には:
IF (key exists)
run update command
ELSE
run insert command
これを記述する最もパフォーマンスの高い方法は何ですか?
ベストアンサー1
トランザクションを忘れないでください。パフォーマンスは良好ですが、単純な (IF EXISTS..) アプローチは非常に危険です。
複数のスレッドが挿入または更新を実行しようとすると、主キー違反が簡単に発生する可能性があります。
@Beau Crawford と @Esteban が提供したソリューションは一般的な考え方を示していますが、エラーが発生しやすいです。
デッドロックや PK 違反を回避するには、次のようなものを使用できます。
begin tran
if exists (select * from table with (updlock,serializable) where key = @key)
begin
update table set ...
where key = @key
end
else
begin
insert into table (key, ...)
values (@key, ...)
end
commit tran
または
begin tran
update table with (serializable) set ...
where key = @key
if @@rowcount = 0
begin
insert into table (key, ...) values (@key,..)
end
commit tran