Ако приемем, че имате уникално ограничение за 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
е ПК на.
Пример за типа нещо е по-долу. Ще трябва също да вземете предвид потенциални условия на състезание в 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