2011-01-11 8 views
2

나는 실제 테이블 데이터 변경 (동일한 값으로 업데이트하는 것이 아니라)에서 작동하는 업데이트 트리거를 만드는 작업을했습니다. 그런 목적으로 복사 표를 작성한 다음 갱신 된 행을 이전 복사 된 것과 비교하기 시작했습니다. 트리거가 완료되면, 그것은 복사 실현하기 위해이 켜지지입니다 : 난 더 이상 트리거에서이 추한 코드를 좋아하지 않아저장 프로 시저 및 트리거

UPDATE CopyTable SET 
    id = s.id, 
    -- many, many fields 
FROM MainTable s WHERE s.id IN (SELECT [id] FROM INSERTED) 
       AND CopyTable.id = s.id; 

를, 그래서 저장 프로 시저에 압축을 푼 :

CREATE PROCEDURE UpdateCopy AS 
BEGIN 
UPDATE CopyTable SET 
    id = s.id, 
    -- many, many fields 
    FROM MainTable s WHERE s.id IN (SELECT [id] FROM INSERTED) 
    AND CopyTable.id = s.id; 
END 

결과는 다음과 같습니다. - 올바르지 않은 오브젝트 이름 'INSERTED'. 이 문제를 어떻게 해결할 수 있습니까?

감사합니다,

+1

당신은 단순히 트리거 내에서 저장 프로 시저를 호출하거나뿐만 아니라 절차 다른 장소를 호출 할 가능성이하려고 : 여기

은 답변입니까? – Sparky

+0

아니요, 트리거에서만 발생합니다. – noober

답변

2

문제 삽입 트리거시에만 사용할 수 있다는 점이다

- 호출하는 트리거 변경 - ID의

DECLARE @idStack VARCHAR(max) 
SET @idStack=',' 
SELECT @[email protected]+ltrim(str(id))+',' FROM INSERTED 

의 목록을 구축하는 트리거 변경 저장된 프로 시저

EXEC updateCopy(@idStack) 

- 절차는 큰되지 않습니다 ID의

CREATE PROCEDURE UpdateCopy(@IDLIST VARCHAR(max)) AS 
BEGIN 
UPDATE CopyTable SET 
    id = s.id, 
    -- many, many fields 

    FROM MainTable s WHERE charindex(','+ltrim(str(s.id))+',',@idList) > 0 
    AND CopyTable.id = s.id; 
END 

성능의 쉼표로 구분 된 목록을 가지고,하지만 당신은 당신이 원하는 것을 할 수 있도록해야한다.

은 그냥 즉시에 입력하지만, OK

+0

멋진 해킹! 고맙습니다. 그러나 트리거 속도를 높이려고 시도 했으므로 선택 사항이 아닙니다. (트리거는 SQLCLR이기 때문에 복사 SQL 스크립트는 ADO.Net을 통해 매번 새로운 쿼리로 호출되고 있으므로 서버에 스크립트를 캐시 할 수있는 저장 프로 시저를 만드는 것이 좋습니다. – noober

4

트리거의 코드를 남겨 실행해야합니다. INSERTED은 트리거 코드에서만 사용 가능한 의사 테이블입니다. 이 아닌이 의사 테이블 값을 전달하려고 시도하면 매우 많은 수의 항목이 포함될 수 있습니다.

이것은 선언적 데이터 액세스 언어 인 T-SQL입니다. 그것은 당신의 평범한 절차 적 프로그래밍 언어가 아닙니다. '코드 재사용'과 같은 일반적인 지혜는 SQL에는 적용되지 않으며 성능 문제 만 발생합니다. 트리거가 속한 곳의 코드를 그대로 둡니다. 다시 팩터링하기 쉽도록 일부 코드 생성 도구를 통해 트리거를 생성하므로 트리거를 쉽게 리팩토링 할 수 있습니다.

+0

나는 Remus에 동의합니다. 내 코드는 작동하지만 Work-around 전용입니다.만약 당신이 그것을해야하는 유일한 이유는 당신이 방아쇠에 못생긴 코드를 좋아하지 않는다면, 그것을 내버려둬 라. 다른 이유가 있다면, 내가 작성한 것들이 주위에서 일할 수있게 해줄 것입니다 .... – Sparky

+0

OK. 사실 SQLCLR 트리거이므로 프로 시저를 만드는 이유는 호출마다 매번 동일한 거대한 텍스트를 SQL 서버에 보내면 성능을 향상 시키려고했습니다. – noober

+0

트리거가 SQLCLR 트리거가 된 이유는 무엇입니까? 아마도 당신이하려는 일에 대해 더 설명해야 할 것입니다. 나는 트리거에 CLR을 사용하는 것을 결코 고려하지 않을 것이다. 보통 SQL보다 처리 속도가 느리기 때문이다. – HLGEM