Forudsat at du har en unik begrænsning på n_id, field
hvilket betyder, at højst én række kan matche, du kan (i det mindste i teorien) bruge en INSTEAD OF
udløser.
Dette ville være nemmere med MERGE
(men det er ikke tilgængeligt før SQL Server 2008), da du skal dække UPDATES
af eksisterende data, INSERTS
(Hvor en NULL
værdien er sat til en NON NULL
one) og DELETES
hvor en NON NULL
værdien er sat til NULL
.
En ting, du skal overveje her, er, hvordan du håndterer UPDATES
der sætter alle kolonnerne i en række til NULL
Jeg gjorde dette under test af koden nedenfor og var ret forvirret i et minut eller to, indtil jeg indså, at dette havde slettet alle rækkerne i basistabellen for en n_id
(hvilket betød, at operationen ikke var reversibel via en anden UPDATE
udmelding). Dette problem kunne undgås ved at have VIEW-definitionen OUTER JOIN
på hvilken som helst tabel n_id
er PK af.
Et eksempel på den type ting er nedenfor. Du skal også overveje potentielle løbsforhold i INSERT
/DELETE
kode angivet, og om du har brug for nogle ekstra låsetip derinde.
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