Could you hire me? Contact me if you like what I’ve done in this article and think I can create value for your company with my skills.

May 27, 2008 / by Zsolt Soczó

SQL Server UPSERT variációk 3.

Eléggé sok teher van most rajtam, ezért nem iparkodok az upsert cuccokkal, de igyekszek utolérni magam.

A harmadik megoldás már kicsit ravaszabb, SQL Server 2005-ös utasításokat is tartalmaz:

create proc dbo.UpsertClient3
  @id int,
  @name nvarchar(100)
as
set xact_abort on
begin transaction

update dbo.Client set name = @name where id = @id
 
insert dbo.Client (id, name)
select * from (values (@id, @name)) t(id, name)
except
select * from dbo.Client as t2 with (updlock, serializable)

commit
go

Az except és az intercept halmazműveletek jól jönnek, hogy az update és az insert csak a számára szükséges adatokat kapja meg. Az update-nél nem használtam, hisz ha egy sor nincs benne a táblában úgyse lehet meg update-elni. Az intercept-tel elő lehetett volna szűrni az adatokat, de minek?
Az insert esetén viszont már nem vagánykodhatunk, ki kell venni a bemeneti halmazból a már céltáblában bennlévő sorokat. (Most, hogy ezt írom eszembe jutott, hogy lehet, hogy ezt is ki lehet sprórolni, ha az IGNORE_DUP_KEY be van állítva a kulcs oszlopra. De valahogy rossz érzésem van ezzel kapcsolatban.)

A példa az előző kettővel ellentétben már nem csak 1 bementi sort képes lekezelni, hanem egy tetszőleges számú bementi halmazt is. Tábla típusú paraméterekkel kiválóan együttműködhet.
A megoldás sebessége kb. az előző kettő szintjén van, de ezt utóbbi többsor-lekezelési lehetőség miatt érdemes megfontolni.

Could you hire me? Contact me if you like what I’ve done in this article and think I can create value for your company with my skills.