2011-02-16 138 views
0

如果我使用這個數據透視表查詢創建一個VIEW,它不可編輯。這些單元格是隻讀的,給我SQL2005錯誤:「沒有行被更新,行2中的數據沒有被提交,更新或插入視圖或函數'VIEWNAME'失敗,因爲它包含派生或常量字段。SQL pivoted table是隻讀的,單元格不能被編輯?

關於如何解決這個問題的任何想法或者像這樣的一個樞軸永遠不可編輯?

SELECT  n_id, 
MAX(CASE field WHEN 'fId' THEN c_metadata_value ELSE ' ' END) AS fId, 
MAX(CASE field WHEN 'sID' THEN c_metadata_value ELSE ' ' END) AS sID, 
MAX(CASE field WHEN 'NUMBER' THEN c_metadata_value ELSE ' ' END) AS NUMBER 
FROM metadata 
GROUP BY n_id 
+0

你對'n_id,field`有一個唯一的約束嗎? – 2011-02-16 02:45:34

回答

2

你必須創建視圖觸發器,因爲直接更新是不可能的:

CREATE TRIGGER TrMyViewUpdate on MyView 
INSTEAD OF UPDATE 
AS 
BEGIN 
    SET NOCOUNT ON; 
    UPDATE MyTable 
    SET ... 
    FROM INSERTED... 
END 
3

假設你有一個唯一約束n_id, field這意味着在大多數一行可以匹配你可以(至少在理論上)使用一個INSTEAD OF觸發器。

這將與MERGE容易(但不是可用,直到SQL Server 2008的),因爲你需要覆蓋現有數據UPDATESINSERTS(其中NULL值設置爲NON NULL一個)和DELETES其中NON NULL值設置爲NULL

有一件事你需要在這裏考慮的是如何應對UPDATES說明測試下面的代碼中設置的所有列在一排NULL我這樣做,是相當混亂的一兩分鐘,直到我意識到,這已刪除基表中n_id的所有行(這意味着該操作無法通過另一個UPDATE語句進行反轉)。這個問題可以通過將VIEW定義OUTER JOIN放到以前的表n_id是PK中來避免。

下面是一個例子。您還需要考慮指示的INSERT/代碼中潛在的爭用條件,以及您是否需要其中一些額外的鎖定提示。

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

如果你有更新和插入,應該也有一個刪除,對不對? – RichardTheKiwi 2011-02-16 03:01:02

相關問題