sql >> Databasteknik >  >> RDS >> Sqlserver

SQL pivoterad tabell är skrivskyddad och celler kan inte redigeras?

Förutsatt att du har en unik begränsning på n_id, field vilket innebär att högst en rad kan matcha du kan (i teorin åtminstone) använda en INSTEAD OF utlösare.

Detta skulle vara enklare med MERGE (men det är inte tillgängligt förrän SQL Server 2008) eftersom du behöver täcka UPDATES av befintliga data, INSERTS (Där en NULL värdet är satt till NON NULL one) och DELETES där en NON NULL värdet är satt till NULL .

En sak du skulle behöva tänka på här är hur du hanterar UPDATES som ställer in alla kolumner i en rad till NULL Jag gjorde detta när jag testade koden nedan och var ganska förvirrad i en minut eller två tills jag insåg att detta hade tagit bort alla rader i bastabellen för en n_id (vilket innebar att operationen inte var reversibel via en annan UPDATE påstående). Detta problem kan undvikas genom att ha VIEW-definitionen OUTER JOIN på vilken som helst tabell n_id är PK för.

Ett exempel på typen av sak är nedan. Du skulle också behöva överväga potentiella tävlingsförhållanden i INSERT /DELETE koden anges och om du behöver några ytterligare låstips där.

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. Hur kan jag få antalet kunder per dag efter unika och återkommande kunder för ett specifikt datum?

  2. 'In'-klausul i SQL-server med flera kolumner

  3. sammanfoga två heltal och resultatet som sträng i SQL

  4. Hur använder jag mysql source-kommandot med en mysql-variabel?