1. ホーム
  2. sql

[解決済み] SQL ServerにおけるINSERT OR UPDATEに関する解決策

2022-03-15 01:22:56

質問

のテーブル構造を想定しています。 MyTable(KEY, datafield1, datafield2...) .

既存のレコードを更新したり、レコードが存在しない場合に新しいレコードを挿入したいことがよくあります。

基本的には

IF (key exists)
  run update command
ELSE
  run insert command

一番パフォーマンスの良い書き方は?

どのように解決するのですか?

トランザクションを忘れてはいけない。パフォーマンスは良いが、単純な(IF EXISTS...)アプローチは非常に危険である。
複数のスレッドがInsertまたはUpdateを実行しようとすると、簡単に 主キー違反になります。

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