특정 열이 특정 값에서 다른 값으로 변경되는 것을 감시하는 테이블에 UPDATE 트리거가 있습니다. 이 경우 단일 UPDATE 문을 통해 다른 테이블의 일부 관련 데이터를 업데이트합니다.
트리거가 수행하는 첫 번째 작업은 업데이트 된 행에이 열의 값이 해당 값에서 변경되었는지 확인하는 것입니다. INSERTED를 DELETED에 조인하고 해당 열의 값을 비교합니다. 자격이 없으면 UPDATE 문이 실행되지 않도록 조기에 구제됩니다.
IF NOT EXISTS (
SELECT TOP 1 i.CUSTNMBR
FROM INSERTED i
INNER JOIN DELETED d
ON i.CUSTNMBR = d.CUSTNMBR
WHERE d.CUSTCLAS = 'Misc'
AND i.CUSTCLAS != 'Misc'
)
RETURN
이 경우 CUSTNMBR은 기본 테이블의 기본 키입니다. 이 테이블에서 큰 업데이트 (예 : 5000+ 행)를 수행하는 경우 CUSTCLAS 열을 건드리지 않아도이 명령문은 AGES를 사용합니다. Profiler에서 몇 분 동안이 진술에서 멈추는 것을 볼 수 있습니다.
실행 계획은 기괴합니다. 3,714 개의 실행과 ~ 1,850 만 개의 출력 행을 가진 삽입 된 스캔을 보여줍니다. CUSTCLAS 열의 필터를 통해 실행됩니다. 이를 (중첩 루프를 통해) 삭제 된 스캔 (CUSTCLAS에서도 필터링 됨)에 결합합니다.이 스캔은 한 번만 실행되며 5000 개의 출력 행이 있습니다.
이 문제를 일으키기 위해 내가 무슨 바보 같은 일을하고 있습니까? 트리거는 여러 행 업데이트를 올바르게 처리해야합니다.
편집 :
나는 또한 이것을 EXISTS가 불쾌한 일을하는 경우와 같이 작성하려고 시도했지만 여전히 끔찍합니다.
DECLARE @CUSTNMBR varchar(31)
SELECT TOP 1 @CUSTNMBR = i.CUSTNMBR
FROM INSERTED i
INNER JOIN DELETED d
ON i.CUSTNMBR = d.CUSTNMBR
WHERE d.CUSTCLAS = 'Misc'
AND i.CUSTCLAS != 'Misc'
IF @CUSTNMBR IS NULL
RETURN