호출 응용 프로그램이 저장 프로 시저를 통해 액세스 할 수있는 SQL Server 2008 데이터베이스를 상속 받았습니다.DML 명령이 저장 프로 시저에서 발행되었는지 여부를 확실하게 식별 할 수 있습니까?
데이터베이스의 각 테이블에는 삽입/업데이트/삭제 작업이 기록되는 섀도우 감사 테이블이 있습니다.
감사 테이블 채우기에 대한 성능 테스트에서는 OUTPUT
절을 사용하여 감사 레코드를 삽입하는 것이 트리거를 사용하는 것보다 20 % 정도 빠르므로 저장 프로 시저에서 구현되었습니다.
그러나이 디자인은 테이블에 대해 직접 실행되는 DML 문을 통해 테이블에 직접 적용된 변경 내용을 추적 할 수 없기 때문에 @@NESTLEVEL
값을 사용하여 트리거를 실행할 것인지 여부를 결정하는 트리거도 구현되었습니다 저장 프로 시저를 통해 실행되는 모든 DML은 @@NESTLEVEL
> 1)이됩니다.
IF @@NESTLEVEL = 1 -- implies call is direct sql so generate history from here
BEGIN
... insert into audit table
가 DML 문을 동적 SQL에서 실행되는 업데이트 또는 @@NESTLEVEL
1 위에 제기되는 다른 상황을 추적하지 않기 때문에이 디자인은 결함이 : 트리거 코드의 몸 즉 이 같이 보입니다.
누구나 저장 프로 시저에 의해 트리거되지 않는 경우에만 트리거에서 실행할 수있는 완전히 신뢰할 수있는 방법을 제안 할 수 있습니까?
아니면 (내 생각에) 이것이 가능하지 않습니까?
방어 적으로 프로그램하는 것이 현명하고, CONTEXT_INFO에 이미 설정되어있는 것에 토큰을 "추가"할 수 있습니까? 마찬가지로 연결 기반이기 때문에 절차가 끝나면 토큰을 지워서는 안됩니까? 그리고 proc가 proc를 호출하면, 이미 존재하지 않는 경우에만 추가/제거해야합니다. 까다로워 질 수는 있지만 그래도 여전히 할 수있는 것처럼 느껴집니다. –
@Philip Kelley, 위의 간단한 예제에서'SET CONTEXT_INFO 0x0'을 사용하여 값을 저장 한 다음 다시 설정할 수 있습니다. 가능성은 거의 끝이 없습니다. 이것은 기계의 단순한 예일 뿐이지 완전하게 포괄적 인 것이 아닙니다. –
감사합니다. 이것은 훌륭한 해결책입니다. –