n_id, field に一意の制約があると仮定します これは、最大で 1 つの行が一致できることを意味します (少なくとも理論上は) INSTEAD OF を使用できます。 引き金。
これは MERGE を使用すると簡単です (ただし、SQL Server 2008 までは利用できません) UPDATES をカバーする必要があるため 既存のデータの INSERTS (NULL 値は NON NULL に設定されています one) および DELETES どこで NON NULL 値は NULL に設定されています .
ここで考慮すべきことの 1 つは、UPDATES に対処する方法です。 行のすべての列を NULL に設定する 以下のコードのテスト中にこれを行ったのですが、n_id のベース テーブル内のすべての行が削除されたことに気付くまで、1 ~ 2 分間かなり混乱していました。 (これは、操作が別の UPDATE によって元に戻せないことを意味していました 声明)。この問題は、VIEW 定義 OUTER JOIN を使用することで回避できます。 テーブル n_id に の PK です。
物の種類の例を以下に示します。 INSERT で潜在的な競合状態を考慮する必要もあります。 /DELETE 示されたコードと、そこに追加のロックのヒントが必要かどうか。
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