Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

A tabela dinâmica SQL é somente leitura e as células não podem ser editadas?


Supondo que você tenha uma restrição exclusiva em n_id, field o que significa que no máximo uma linha pode corresponder, você pode (pelo menos em teoria) usar um INSTEAD OF acionar.

Isso seria mais fácil com MERGE (mas isso não está disponível até o SQL Server 2008), pois você precisa cobrir UPDATES de dados existentes, INSERTS (Onde um NULL o valor é definido como um NON NULL one) e DELETES onde um NON NULL o valor está definido como NULL .

Uma coisa que você precisa considerar aqui é como lidar com UPDATES que define todas as colunas em uma linha para NULL Fiz isso durante o teste do código abaixo e fiquei bastante confuso por um minuto ou dois até perceber que isso havia excluído todas as linhas da tabela base para um n_id (o que significava que a operação não era reversível por meio de outro UPDATE declaração). Este problema pode ser evitado com a definição de VIEW OUTER JOIN em qualquer tabela n_id é o PK de.

Um exemplo do tipo de coisa está abaixo. Você também precisaria considerar possíveis condições de corrida no INSERT /DELETE código indicado e se você precisa de algumas dicas de bloqueio adicionais lá.
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