<p>N’oubliez pas les transactions. La performance est bonne, mais l’approche simple (IF EXISTS..) est très dangereuse.</p>
<p>Lorsque plusieurs threads essaieront d’effectuer un Insert-or-update, vous pouvez facilement obtenir une violation de clé primaire.</p>
<p>Les solutions fournies par <span class="mention">@Beau</span> Crawford et <span class="mention">@Esteban</span> montrent l’idée générale mais sont sujettes aux erreurs.</p>
<p>Pour éviter les interblocages et les violations de clé primaire, vous pouvez utiliser quelque chose comme ceci :</p>
<pre><code class="lang-auto">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
</code></pre>
<p>ou</p>
<pre><code class="lang-auto">begin tran
update table with (serializable) set ...
where key = @key
if @@rowcount = 0
begin
insert into table (key, ...) values (@key,..)
end
commit tran
</code></pre>