Za předpokladu, že máte jedinečné omezení pro n_id, field
což znamená, že maximálně jeden řádek se může shodovat, můžete (alespoň teoreticky) použít INSTEAD OF
spoušť.
S MERGE
by to bylo jednodušší (ale to není k dispozici až do SQL Server 2008), protože potřebujete pokrýt UPDATES
existujících dat, INSERTS
(Kde je NULL
hodnota je nastavena na NON NULL
jedna) a DELETES
kde NON NULL
hodnota je nastavena na NULL
.
Jedna věc, kterou byste zde měli zvážit, je, jak se vypořádat s UPDATES
který nastaví všechny sloupce v řádku na NULL
Udělal jsem to během testování kódu níže a byl jsem minutu nebo dvě docela zmatený, dokud jsem si neuvědomil, že tím byly odstraněny všechny řádky v základní tabulce pro n_id
(což znamenalo, že operace nebyla vratná přes další UPDATE
tvrzení). Tomuto problému by se dalo předejít použitím definice VIEW OUTER JOIN
na jakoukoli tabulku n_id
je PK of.
Příklad typu věci je níže. V INSERT
byste také měli vzít v úvahu potenciální rasové podmínky /DELETE
uvedený kód a zda tam potřebujete nějaké další rady pro zamykání.
CREATE TRIGGER trig
ON pivoted
INSTEAD OF UPDATE
AS
BEGIN
SET nocount ON;
DECLARE @unpivoted TABLE (
n_id INT,
field VARCHAR(10),
c_metadata_value VARCHAR(10))
INSERT INTO @unpivoted
SELECT *
FROM inserted UNPIVOT (data FOR col IN (fid, sid, NUMBER) ) AS unpvt
WHERE data IS NOT NULL
UPDATE m
SET m.c_metadata_value = u.c_metadata_value
FROM metadata m
JOIN @unpivoted u
ON u.n_id = m.n_id
AND u.c_metadata_value = m.field;
/*You need to consider race conditions below*/
DELETE FROM metadata
WHERE NOT EXISTS(SELECT *
FROM @unpivoted u
WHERE metadata.n_id = u.n_id
AND u.field = metadata.field)
INSERT INTO metadata
SELECT u.n_id,
u.field,
u.c_metadata_value
FROM @unpivoted u
WHERE NOT EXISTS (SELECT *
FROM metadata m
WHERE m.n_id = u.n_id
AND u.field = m.field)
END