2009-08-26 3 views
0

테이블이 있는데, [MYTABLE], FOR 삽입, 업데이트 트리거와 함께 호출하도록합니다.T-SQL 트리거 효과는 다른 코드를 호출하기 전에 변경

트리거는 [MYTABLE]의 변경 사항에 따라 일부 작업을 수행하는 저장 프로 시저를 실행해야합니다. 저장 프로 시저의 코드를 트리거로 옮길 수 없습니다. 트리거을 변경 한 후 을 실행하기 때문에

지금까지 너무 좋아 ..., 저장 프로 시저는 [삽입] 또는 [삭제] 메타 테이블에 액세스 할 필요가 없습니다.

그러나 ... 트리거 하나의 추가 필드 (a [LASTMODIFIED] smalldatetime으로) 그렇게 저장된 프로 시저가 처리 데이터를 사용하여 변경할 필요가있다. 이것은 이 아니고입니다. 따라서 저장 프로 시저가 삽입/업데이트 된 것을 볼 수 있습니다. 프로 시저가 트리거를 업데이트하는 업데이트에 포함되지 않은 다른 레코드를 기반으로 여러 가지 작업을 수행 할 수 있습니다. 내 트리거 (I 재귀 트리거가 꺼져있는 경우) 모든아무것도하지 않는 것 중 하나가, [LASTMODIFIED]를 변경하거나 저장 프로 시저를 호출 두 번 끝날 경우

문제입니다 - 한 번 때문에 원래 트리거링 변경 사항이 있었고, 다시 변경된 이유는 [LastModified]입니다.

어떻게이 문제를 얻을 수 있도록 (a)에 [LASTMODIFIED] 각각의 변화와 함께 업데이트되는 (b)는 저장 프로 시저 만이[LASTMODIFIED]의 새로운 값에 액세스 할 수 있습니다 후라고합니다 ?

나는 생각하고있는 두 가지 아이디어가 있지만, 그들은 우스운 냄새가 난다. 그래서 나는 좀 더 솔직한 해결책이 있는지보기를 원한다.

편집 :

좋아, 여기에 솔루션입니다 I가 지금까지, 어쩌면 논의 도움이됩니다 :

1. 두 개의 트리거를. 하나의 "INSTEAD OF"트리거는 사용자의 레코드 업데이트를 처리하고 LastModified를 변경하지만 에서 SP (수정 된 열을 기반으로 알 수 있음)가 올 경우 신속하게 반환합니다. 다른 하나는 EXEC를 호출하는 "AFTER"트리거가됩니다. 이 트리거는 Last Modified 열 이 이미에 적용된 업데이트를 INSTEAD OF 트리거로 가져옵니다. 적어도 그것이 그것이 작동하는 방법이되기를 바랍니다.

2. ModifiedDate를 다른 테이블로 이동하십시오. 그런 식으로 하나의 AFTER INSERT/UPDATE 트리거를 가질 수 있습니다. 사용자가 INSERT/UPDATE를 시작하고 감사 레코드를 다른 테이블에 추가하고 SP를 호출하는 경우. 그러면 SP가 트리거를 다시 발생시키는 다른 레코드를 수정하지만 더 많은 작업을하지 않고도 상황을 신속하게 파악하고 반환합니다.

첫 번째 솔루션의 단점은 트리거의 열 목록을 유지해야하므로 업데이트의 대체 항목이 의도 한 작업을 실제로 수행한다는 것입니다. (목록에 열을 추가 했으므로 ModifiedDate를 사용할 수 없습니다. INSERT INTO tbl FROM이 삽입되었으므로 열을 지정해야합니다.)

+0

초기 INSERT/UPDATE는 어떻게 수행됩니까? 그리고 방아쇠를 사용해야합니까? 이유는 전체 이벤트 과정이 저장 프로 시저 내에 캡슐화 될 수 있다는 것입니다 (트리거가 필요하지 않음). –

답변

3

IF UPDATE (LastModified) 명령을 사용해 보셨습니까?

CREATE TRIGGER XYZ ON MYTABLE 
FOR INSERT, UPDATE 
AS 
BEGIN 
IF UPDATE(LastModified) 
    RETURN 
ELSE 
    BEGIN 
    UPDATE MYTABLE SET LastModified = GETDATE() 
    FROM MYTABLE INNER JOIN INSERTED ON MYTABLE.ID = INSERTED.ID 
    EXEC TheStoreProc 
    END 
END; 
+0

이것은 워크 플로의 잘못된 쪽에서 호출되는 EXEC 문제를 해결하지만 트리거에 의해 업데이트되어야하는 LastModified는 실제로 변경하지 않습니다. – richardtallent

+0

스크립트를 수정하고 이제 테이블을 업데이트 한 다음 스크립트를 실행합니다. 트리거가 두 번 트리거되지만 내부 실행은 즉시 종료됩니다. – Rodrigo

+0

Rodrigo - 감사합니다. 그러나 이것이 완료되면 EXEC가 LastModified를 "보았"습니까? 트리거가 일종의 암시 적 트랜잭션 내에서 작동하지 않는 한,이를 볼 수 있다는 것은 의미가 있습니다. – richardtallent

0

설명하는 흐름을 잘 모르겠습니다. 그것이 :

  1. 기록이 업데이트
  2. 업데이트 트리거 시저를 호출
  3. 트리거 업데이트 트리거가 한, 잘 작동합니다 다른 시저

를 호출

  • 필드 LASTMODIFIED은 " 다른 proc "은 같은 테이블을 업데이트하지 않습니다. 트리거를 다시 시작합니다. 은 "다른 PROC"입니다 다시 테이블을 갱신하는 경우

    , 당신은 아마도 이전에 "다른 시저"를 호출하는 트리거에 해당 업데이트를 를 이동할 수 있습니다.

    그게 도움이 될까요?

  • +0

    불행히도, 그게 정확히 무슨 일이야. SP는 "원래"트리거와 동일한 * 레코드를 절대 업데이트하지 않지만 트리거를 다시 호출하는 다른 업데이트를 업데이트합니다. 그래서, 재귀의 기회는 없지만, 그것은 여전히 ​​지저분한 작은 원 스텝 루프입니다. 불행하게도 SP 코드를 트리거로 옮기는 것은 좋지 않습니다 (SP는 * 다른 레코드에만 영향을 미치므로 INSTEAD OF 트리거는 원스텝 재귀를 감소시키지 않으므로 코드 유지 관리가 쉽지 않습니다) 테이블은 동일한 SP를 호출합니다. 차라리보기를 사용하고 싶지만 이번에는 전화를 걸지 마십시오. – richardtallent

    관련 문제