假設你有一個唯一約束n_id, field
這意味着在大多數一行可以匹配你可以(至少在理論上)使用一個INSTEAD OF
觸發器。
這將與MERGE
容易(但不是可用,直到SQL Server 2008的),因爲你需要覆蓋現有數據UPDATES
,INSERTS
(其中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
你對'n_id,field`有一個唯一的約束嗎? – 2011-02-16 02:45:34