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.

December 17, 2007 / by Zsolt Soczó

SQL Server 2008 újdonságok 7. – MERGE utasítás

Hányszor ír le az ember ehhez hasonló sql blokkokat?

if exists(select * from Tabla where oszl = @ize))
update Tabla … where oszl = @ize
else
insert Tabla (…) values (@ize, …)

Az egy dolog, hogy ilyenkor kétszer kell nekimenni a táblának, ami teljesítményveszteséget okoz, de még arra is oda kell figyelni, hogy attól, hogy az if azt monda, nem létezik a sor, az insert idejében már lehet, hogy egy párhuzamos folyamat beszúrta azt, pofára ejtve az insertet. Megfelelő izolációs szinttel persze ez kivédhető, de akkor meg a konkurencia csökken. A fő gond az, hogy nem volt olyan utasítás, ami ha már megnézte, hogy létezik-e a sor, azon nyomban valamilyen műveletet végez rajta (update vagy delete), vagy betömi a lukat (insert). Jöhet a MERGE.

A merge lényege, hogy van egy forrás adathalmazunk és egy cél táblánk. A kettő között join jellegű kapcsolatot adunk meg, amely segítségével pároztatjuk a két oldal sorait. Miközben soronként megy a pároztatás annak sikerétől vagy sikertelenségétől függően különböző DML műveleteket hajthatunk végre.

A következő példát arcátlanul elloptam a BOL-ból:

MERGE Production.ProductInventory AS pi
USING 
(SELECT ProductID, SUM(OrderQty) 
FROM Sales.SalesOrderDetail sod
JOIN Sales.SalesOrderHeader soh
ON sod.SalesOrderID = soh.SalesOrderID
AND soh.OrderDate = GETDATE()
GROUP BY ProductID) 
AS src (ProductID, OrderQty)
ON (pi.ProductID = src.ProductID)
WHEN MATCHED AND pi.Quantity - src.OrderQty <> 0 
    THEN UPDATE SET pi.Quantity = pi.Quantity - src.OrderQty
WHEN MATCHED AND pi.Quantity - src.OrderQty = 0 
    THEN DELETE;

Ez leválogatja a ma eladott termékeket, az id-jüket és az ezen a napon eladott össz mennyiséget. Ezen adatok alapján babrán a raktárkészleten, az ProductInventory táblán.
Ha a ProductID-nek megfelelő sor van a ProductInventory-ban és levonva a ma eladott cuccokat még marad raktáron, akkor update-eljük a raktáron levő termékszámot. Ha pont annyit adtak ma el, amennyi raktáron volt, akkor kitörlik a raktáros sort, minek egy 0-s sor (persze, ez most egy mesterséges feladat, nem feltétlen törölnénk ki élőben).

Lehetne még írni műveleteket azokra az estekre is, ha valamelyik oldanak nincs párja a másik oldalon. Majd, ha aludtam egyet, írok ilyen példát. :)

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.