이 최대 하나 개의 행이 당신에게 수와 일치 할 수 있음을 의미하는 당신이 n_id, field
에 고유 제한 조건을 가정 (적어도 이론적으로) INSTEAD OF
방아쇠를 사용하십시오.
이 MERGE
와 쉬울 것이다 (하지만이 SQL 서버 2008까지 사용할 수 없습니다) 당신과 DELETES
NON NULL
값 (A NULL
값이 NON NULL
하나로 설정됩니다) 기존 데이터의 UPDATES
, INSERTS
을 충당하기 위해 필요로하는 NULL
으로 설정됩니다.
여기서 고려해야 할 한 가지는 행의 모든 열을 NULL
으로 설정하는 UPDATES
에 대처하는 방법입니다. 아래 코드를 테스트하는 동안이 작업을 수행했는데 실제로 실현 될 때까지 1-2 분 동안 매우 혼란스러워했습니다. 이로 인해 기본 테이블의 모든 행이 n_id
으로 삭제되었습니다 (이는 조작이 다른 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
'n_id, field'에 고유 한 제약이 있습니까? –