2014-12-09 2 views
1

레코드를 삭제하려고 할 때이 트리거를 작동 시키려고합니다. 일할 수있는 방법은 누군가가 레코드를 삭제하려고 시도 할 때 TbAudit 테이블에 감사 레코드를 삽입하고, 모든 컬럼은 NOT NULL 제약 조건을 갖습니다. 그러나 레코드를 삭제하려고하면 어떤 이유로 레코드가 삭제되고 롤백되지만 select 문 내의 모든 변수가 NULL 값을 가져오고 있기 때문에 이해가 안되기 때문에 그 이유는 알지 못합니다. "삭제 된"테이블. 도와주세요. 나는이 방법에 문제가있을 수 있습니다 생각삭제 후 SQL 삭제 된 Pseudotable에 Null 값이 있습니까?

USE BdPlan 
GO 
CREATE TRIGGER TrAudit 
    ON Plan.TPlan 
    AFTER DELETE 
AS 
BEGIN 
DECLARE @IdPlan = int, 
     @IdEmployee int, 
     @Month int, 
     @Year int 

ROLLBACK 
PRINT 'CANT DELETE RECORDS' 

-- All variables are getting NULL 

SELECT @IdPlan = D.IdPlan,    
     @IdEmployee = D.IdEmployee , 
     @Month = D.Month,    
     @Year = D.Year     

FROM deleted AS D 

INSERT INTO BdAudit.dbo.TbAudit 
      VALUES 
       (
       @IdPlan, 
       @IdEmployee, 
       @Month, 
       @Year, 
       SUSER_NAME(), 
       GETDATE() 
       ) 
END 

답변

0

: 트랜잭션이 롤백 된 후에는 DELETED pseudotable에 액세스하려고

  • -이 롤백 후 제로 행을해야합니다 (아래 참조)
  • 트리거는 단일 행 삭제 처리를 시도 - 또한 아니다

을 삭제 다중 행을 처리 할 수 ​​있어야합니다 ROLLBACK 전에 Deleted pseudotable의 Audit 테이블에 직접 삽입하는 것은 물론 감사 데이터를 롤백합니다.

ALTER trigger d_foo ON FOO AFTER DELETE 
AS BEGIN 
    DECLARE @Temp AS TABLE 
    (
     ID INT, 
     -- Obviously add all your fields go here 
    ); 

    INSERT INTO @Temp(ID) 
     SELECT ID FROM DELETED; 

    ROLLBACK TRAN; 

    insert into fooaudit(id) 
     select id from @Temp; 
END; 
:

From here 당신이 @Temporary 테이블 변수에 감사 할 데이터를 캐시 할 수 있습니다 분명하다, 다음 다음합니다 (@Temp 테이블을 취소하지 않음) ROLLBACK, 그리고 감사의 삽입을 할

Simplified SqlFiddle here 다중 행 삭제.

확인을 위해 DELETED pseudotable에는 트리거에서 ROLLBACK 이후 0 행이 포함됩니다 (이 경우 modified Fiddle demonstrates).

+1

절대 천재, 정말 고마워. 그것은 트릭을했다!! – jebc88

+1

트리거 내에서 ROLLBACK을 사용할 때주의하십시오. 외부 코드에 명시 적 트랜잭션이 있으면 롤백 또는 커밋 할 트랜잭션이 없으므로 예외가 발생합니다. RAISERROR를 사용하면 호출 응용 프로그램에서 무언가가 발생했다는 것을 알 수 있고 일치하지 않는 트랜잭션이 발생하지 않도록하는 것이 좋습니다. –

관련 문제