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