Giả sử bạn có một ràng buộc duy nhất đối với n_id, field
có nghĩa là ít nhất một hàng có thể khớp, bạn có thể (trên lý thuyết là ít nhất) sử dụng INSTEAD OF
Kích hoạt.
Điều này sẽ dễ dàng hơn với MERGE
(nhưng điều đó không khả dụng cho đến SQL Server 2008) vì bạn cần phải bao gồm UPDATES
dữ liệu hiện có, INSERTS
(Trường hợp NULL
giá trị được đặt thành NON NULL
một) và DELETES
trong đó NON NULL
giá trị được đặt thành NULL
.
Một điều bạn cần cân nhắc ở đây là cách đối phó với UPDATES
đặt tất cả các cột trong một hàng thành NULL
Tôi đã làm điều này trong khi kiểm tra mã bên dưới và khá bối rối trong một hoặc hai phút cho đến khi tôi nhận ra rằng điều này đã xóa tất cả các hàng trong bảng cơ sở cho một n_id
(có nghĩa là thao tác này không thể hoàn nguyên qua UPDATE
khác bản tường trình). Có thể tránh được vấn đề này bằng cách sử dụng định nghĩa VIEW OUTER JOIN
lên bảng nào n_id
là PK của.
Dưới đây là một ví dụ về loại điều này. Bạn cũng cần phải xem xét các điều kiện chủng tộc tiềm năng trong INSERT
/ DELETE
mã được chỉ ra và liệu bạn có cần thêm một số gợi ý khóa trong đó hay không.
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