Suponiendo que tiene una restricción única en n_id, field
lo que significa que como máximo una fila puede coincidir, puede (al menos en teoría) usar un INSTEAD OF
generar.
Esto sería más fácil con MERGE
(pero eso no está disponible hasta SQL Server 2008) ya que necesita cubrir UPDATES
de datos existentes, INSERTS
(Donde un NULL
el valor se establece en NON NULL
uno) y DELETES
donde un NON NULL
el valor se establece en NULL
.
Una cosa que debe considerar aquí es cómo hacer frente a UPDATES
que establece todas las columnas en una fila en NULL
Hice esto durante la prueba del código a continuación y estuve bastante confundido por un minuto o dos hasta que me di cuenta de que esto había eliminado todas las filas en la tabla base para un n_id
(lo que significaba que la operación no era reversible a través de otro UPDATE
declaración). Este problema podría evitarse teniendo la definición VIEW OUTER JOIN
en cualquier tabla n_id
es el PK de.
A continuación se muestra un ejemplo del tipo de cosa. También deberá considerar las posibles condiciones de carrera en el INSERT
/DELETE
código indicado y si necesita algunas sugerencias de bloqueo adicionales allí.
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