Supponendo che tu abbia un vincolo univoco su n_id, field
il che significa che al massimo una riga può corrispondere puoi (almeno in teoria) usare un INSTEAD OF
grilletto.
Sarebbe più facile con MERGE
(ma non è disponibile fino a SQL Server 2008) poiché è necessario coprire UPDATES
dei dati esistenti, INSERTS
(Dove un NULL
il valore è impostato su un NON NULL
uno) e DELETES
dove un NON NULL
il valore è impostato su NULL
.
Una cosa che dovresti considerare qui è come affrontare UPDATES
che imposta tutte le colonne di una riga su NULL
L'ho fatto durante il test del codice seguente e sono rimasto abbastanza confuso per un minuto o due finché non mi sono reso conto che questo aveva eliminato tutte le righe nella tabella di base per un n_id
(il che significava che l'operazione non era reversibile tramite un altro UPDATE
dichiarazione). Questo problema potrebbe essere evitato avendo la definizione VIEW OUTER JOIN
su qualsiasi tabella n_id
è la PK di.
Un esempio del tipo di cosa è sotto. Dovresti anche considerare le potenziali condizioni di gara nel INSERT
/DELETE
codice indicato e se sono necessari ulteriori suggerimenti per il blocco.
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