Zakładając, że masz unikalne ograniczenie na n_id, field co oznacza, że co najwyżej jeden wiersz może pasować, możesz (przynajmniej teoretycznie) użyć INSTEAD OF cyngiel.
Byłoby to łatwiejsze dzięki MERGE (ale to nie jest dostępne do SQL Server 2008), ponieważ musisz uwzględnić UPDATES istniejących danych, INSERTS (Gdzie NULL wartość jest ustawiona na NON NULL jeden) i DELETES gdzie NON NULL wartość jest ustawiona na NULL .
Jedną rzeczą, którą musisz wziąć pod uwagę, jest to, jak radzić sobie z UPDATES które ustawiają wszystkie kolumny w wierszu na NULL Zrobiłem to podczas testowania poniższego kodu i byłem dość zdezorientowany przez minutę lub dwie, dopóki nie zdałem sobie sprawy, że to usunęło wszystkie wiersze w tabeli bazowej dla n_id (co oznaczało, że operacja nie była odwracalna przez inną UPDATE oświadczenie). Tego problemu można uniknąć, stosując definicję VIEW OUTER JOIN na jakąkolwiek tabelę n_id jest PK.
Przykład tego typu rzeczy znajduje się poniżej. Musisz również wziąć pod uwagę potencjalne warunki wyścigu w INSERT /DELETE wskazany kod i czy potrzebujesz tam dodatkowych wskazówek dotyczących blokowania.
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