sql >> Base de Datos >  >> RDS >> Sqlserver

¿La tabla dinámica de SQL es de solo lectura y las celdas no se pueden editar?

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