SQL pivoted table is read-only and cells can't be edited?

前端 未结 2 1525
野趣味
野趣味 2021-01-16 18:01

If I create a VIEW using this pivot table query, it isn\'t editable. The cells are read-only and give me the SQL2005 error: \"No row was updated. The data in row 2 was n

相关标签:
2条回答
  • 2021-01-16 18:20

    You'll have to create trigger on view, because direct update is not possible:

    CREATE TRIGGER TrMyViewUpdate on MyView
    INSTEAD OF UPDATE
    AS
    BEGIN
       SET NOCOUNT ON;
       UPDATE MyTable
       SET ...
       FROM INSERTED...
    END
    
    0 讨论(0)
  • 2021-01-16 18:29

    Assuming you have a unique constraint on n_id, field which means that at most one row can match you can (in theory at least) use an INSTEAD OF trigger.

    This would be easier with MERGE (but that is not available until SQL Server 2008) as you need to cover UPDATES of existing data, INSERTS (Where a NULL value is set to a NON NULL one) and DELETES where a NON NULL value is set to NULL.

    One thing you would need to consider here is how to cope with UPDATES that set all of the columns in a row to NULL I did this during testing the code below and was quite confused for a minute or two until I realised that this had deleted all the rows in the base table for an n_id (which meant the operation was not reversible via another UPDATE statement). This issue could be avoided by having the VIEW definition OUTER JOIN onto what ever table n_id is the PK of.

    An example of the type of thing is below. You would also need to consider potential race conditions in the INSERT/DELETE code indicated and whether you need some additional locking hints in there.

    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  
    
    0 讨论(0)
提交回复
热议问题