ストアドプロシージャへの挿入で同時実行の問題が発生しています。手順の関連部分は次のとおりです。
select @_id = Id from table1 where othervalue = @_othervalue
IF( @_id IS NULL)
BEGIN
insert into table1 (othervalue) values (@_othervalue)
select @_id = Id from table1 where othervalue = @_othervalue
END
これらのストアドプロシージャの3つまたは4つを同時に実行すると、複数の挿入が発生することがあります。
私はこれを次のように修正することを計画しています:
insert into table1 (othervalue)
select TOP(1) @_othervalue as othervalue from table1 WITH(UPDLOCK)
where NOT EXISTS ( select * from table1 where othervalue = @_othervalue )
select @_id = Id from table1 where othervalue = @_othervalue
問題は、SQLサーバーに重複せずに同時に挿入する方法ですか? TOPを使用して挿入する必要があるのは、邪魔になるだけです。
serializable
ヒントを使用してmergeステートメントを使用できます。
merge table1 with (serializable) as T
using (select @_othervalue as othervalue) as S
on T.othervalue = S.othervalue
when not matched then
insert (othervalue) values (othervalue);
「othervalue」列で重複を望まない場合は、unique constraint
その列。クエリは次のようになります。
ALTER TABLE table1
ADD CONSTRAINT unique_c_othervalue UNIQUE(othervalue)
クエリが 'othervalue'列に重複する値を挿入しようとした場合、これはエラーを返します。
@StanleyJohnsが推奨するような一意の制約を使用します。次に、挿入ステートメントをBEGIN TRY END TRYで囲みます。
select @_id = Id from table1 where othervalue = @_othervalue
IF( @_id IS NULL)
BEGIN
BEGIN TRY
insert into table1 (othervalue) values (@_othervalue)
select @_id = Id from table1 where othervalue = @_othervalue
END TRY
BEGIN CATCH
select @_id = Id from table1 where othervalue = @_othervalue
END CATCH
END