Angenommen, Sie haben eine eindeutige Einschränkung für n_id, field
was bedeutet, dass höchstens eine Zeile übereinstimmen kann, können Sie (zumindest theoretisch) einen INSTEAD OF
verwenden Abzug.
Einfacher geht das mit MERGE
(aber das ist bis SQL Server 2008 nicht verfügbar), da Sie UPDATES
abdecken müssen vorhandener Daten, INSERTS
(Wo ein NULL
value wird auf NON NULL
gesetzt eins) und DELETES
wo ein NON NULL
Wert wird auf NULL
gesetzt .
Eine Sache, die Sie hier beachten sollten, ist der Umgang mit UPDATES
die alle Spalten in einer Zeile auf NULL
setzen Ich habe dies beim Testen des folgenden Codes getan und war ein oder zwei Minuten lang ziemlich verwirrt, bis mir klar wurde, dass dies alle Zeilen in der Basistabelle für einen n_id
gelöscht hatte (was bedeutete, dass der Vorgang nicht über ein weiteres UPDATE
rückgängig gemacht werden konnte Aussage). Dieses Problem könnte durch die VIEW-Definition OUTER JOIN
vermieden werden auf eine beliebige Tabelle n_id
ist die PK von.
Ein Beispiel für die Art der Sache ist unten. Sie müssten auch potenzielle Rennbedingungen im INSERT
berücksichtigen /DELETE
angezeigten Code und ob Sie dort zusätzliche Hinweise zum Sperren benötigen.
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