Ervan uitgaande dat u een unieke beperking heeft op n_id, field wat betekent dat er maximaal één rij kan overeenkomen, kun je (in theorie tenminste) een INSTEAD OF gebruiken trekker.
Dit zou gemakkelijker zijn met MERGE (maar dat is niet beschikbaar tot SQL Server 2008) omdat u UPDATES moet behandelen van bestaande gegevens, INSERTS (Waar een NULL waarde is ingesteld op NON NULL one) en DELETES waarbij een NON NULL waarde is ingesteld op NULL .
Een ding dat u hier zou moeten overwegen, is hoe u omgaat met UPDATES die alle kolommen op een rij instelt op NULL Ik deed dit tijdens het testen van de onderstaande code en was een minuut of twee behoorlijk in de war totdat ik me realiseerde dat dit alle rijen in de basistabel voor een n_id had verwijderd (wat betekende dat de operatie niet omkeerbaar was via een andere UPDATE uitspraak). Dit probleem kan worden vermeden door de VIEW-definitie OUTER JOIN . te gebruiken op welke tafel dan ook n_id is de PK van.
Een voorbeeld van het soort ding staat hieronder. U moet ook rekening houden met mogelijke race-omstandigheden in de INSERT /DELETE code aangegeven en of je daar wat extra vergrendelingstips nodig hebt.
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