Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

La tabella pivot SQL è di sola lettura e le celle non possono essere modificate?

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