SQL Server 2008 újdonságok 22. – Composable DML (DML table source)

Ez egy jó dolog lesz.
Az OUTPUT kulcsszó már ismerős lehet 2005-ből, egy DML (INSERT, UPDATE, DELETE) művelet által érintett sorokat lehetett kipakolni tábla típusú változóba vagy lokális változókba.

A 2008-ban ezt tovább bővítették, így a kimenet bemenetként szolgálhat egy INSERT utasítás részére, azaz, össze lehet csövezni mindenféle átmeneti tábla nélkül a DML műveleteket. Innen a komponálható DML elnevezés.

Lássunk egy egyszerű példát:

create table t1(col1 int);
create table t2(col1 int);

insert into t1 values (1),(2),(3);

insert into t2(col1)
select col1 from 
(update t1 
set col1 = col1 + 1 
output inserted.col1) as d;

select * from t2
col1
-----------
2
3
4

Egyszerűen nevet kell adni az output kimentének, és máris táblaként kezelhetjük.

Bob barátunktól átemelek egy összetettebb auditálós példát:

CREATE TABLE Stock (Stock VARCHAR(10) PRIMARY KEY, Qty INT CHECK (Qty > 0));
CREATE TABLE Trades (Stock VARCHAR(10) PRIMARY KEY, Delta INT CHECK (Delta <> 0));
CREATE TABLE AuditChanges (Action varchar(6), Stock VARCHAR(6), Qty INT);
GO

INSERT Stock VALUES('MSFT', 10), ('BOEING', 5);
INSERT Trades VALUES('MSFT', 5), ('BOEING', -5), ('GE', 3);
GO

INSERT INTO AuditChanges
SELECT * FROM
(
MERGE Stock S
  USING Trades T
  ON S.Stock = T.Stock
  WHEN MATCHED AND (Qty + T.Delta = 0) THEN
    DELETE
  WHEN MATCHED THEN
    UPDATE SET Qty += T.Delta
  WHEN NOT MATCHED THEN
    INSERT VALUES(Stock, T.Delta)
  OUTPUT $action, T.Stock, inserted.Qty
) tab (action, stock, qty);
GO

select * from AuditChanges
Action Stock  Qty
------ ------ -----------
DELETE BOEING NULL
INSERT GE     3
UPDATE MSFT   15

Aranyos. De azért tudni kell róla, hogy ez csak egy kezdemény még az SQL Serverben, v 0.1, majd a következő verziókban teljesítik ki. Nem használható csak INSERT-ben az eredmény, csak táblába tud beszúrni, view-ba nem, nem lehet a céltáblán trigger, nem lehet rajta fk vagy pk, nem dolgozhat replikációban. Kb. arra jó, amire a második példa is mutatja, logolni bizonyos műveleteket.