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

SQL pivotabel tabel er skrivebeskyttet, og celler kan ikke redigeres?

Forudsat at du har en unik begrænsning på n_id, field hvilket betyder, at højst én række kan matche, du kan (i det mindste i teorien) bruge en INSTEAD OF udløser.

Dette ville være nemmere med MERGE (men det er ikke tilgængeligt før SQL Server 2008), da du skal dække UPDATES af eksisterende data, INSERTS (Hvor en NULL værdien er sat til en NON NULL one) og DELETES hvor en NON NULL værdien er sat til NULL .

En ting, du skal overveje her, er, hvordan du håndterer UPDATES der sætter alle kolonnerne i en række til NULL Jeg gjorde dette under test af koden nedenfor og var ret forvirret i et minut eller to, indtil jeg indså, at dette havde slettet alle rækkerne i basistabellen for en n_id (hvilket betød, at operationen ikke var reversibel via en anden UPDATE udmelding). Dette problem kunne undgås ved at have VIEW-definitionen OUTER JOIN på hvilken som helst tabel n_id er PK af.

Et eksempel på den type ting er nedenfor. Du skal også overveje potentielle løbsforhold i INSERT /DELETE kode angivet, og om du har brug for nogle ekstra låsetip derinde.

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  


  1. Kan ikke slippe nøglen, selvom den eksisterer:Fejlkode:1091

  2. Maks. inden for en tidsramme med datoduplikater

  3. #1411 - Forkert datetime-værdi for funktionen str_to_date på INSERT INTO...SELECT

  4. Indlejrede transaktioner i postgresql 8.2?