Dengan asumsi Anda memiliki batasan unik pada n_id, field
yang berarti bahwa paling banyak satu baris dapat cocok, Anda dapat (setidaknya secara teori) menggunakan INSTEAD OF
pemicu.
Ini akan lebih mudah dengan MERGE
(tetapi itu tidak tersedia hingga SQL Server 2008) karena Anda harus mencakup UPDATES
dari data yang ada, INSERTS
(Di mana NULL
nilai diatur ke NON NULL
satu) dan DELETES
di mana NON NULL
nilai diatur ke NULL
.
Satu hal yang perlu Anda pertimbangkan di sini adalah bagaimana mengatasi UPDATES
yang mengatur semua kolom dalam satu baris ke NULL
Saya melakukan ini selama pengujian kode di bawah ini dan cukup bingung selama satu atau dua menit sampai saya menyadari bahwa ini telah menghapus semua baris di tabel dasar untuk n_id
(yang berarti operasi tidak dapat dibatalkan melalui UPDATE
lain penyataan). Masalah ini dapat dihindari dengan memiliki definisi VIEW OUTER JOIN
ke tabel apa pun n_id
adalah PK dari.
Contoh jenis barang di bawah ini. Anda juga perlu mempertimbangkan kondisi balapan potensial di INSERT
/DELETES
kode yang ditunjukkan dan apakah Anda memerlukan beberapa petunjuk penguncian tambahan di sana.
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