2014-11-05 2 views
1

나는이 다음 트리거는 우리의 시스템은 모든 작업과 함께, 핀란드와 다른 작업을 일시 중지 재생 작동SQL 트리거 조용히 실패

CREATE TRIGGER [dbo].[LastActionTrigger] on [dbo].[PlanningAction] 
AFTER INSERT AS 

BEGIN 

DECLARE @ActionID BIGINT 
DECLARE @ActionNameID BIGINT 
DECLARE @MilestonePlanningID BIGINT 
DECLARE @Name VARCHAR(MAX) 
DECLARE @log as varchar(max) 
DECLARE @cmdtxt as varchar(255) 

SELECT @ActionID = i.ActionID, @ActionNameID = i.ActionNameID, @MilestonePlanningID = i.MilestonePlanningID 
FROM Inserted i 


IF @ActionNameID NOT IN (10,11,12) 
    BEGIN 

    UPDATE MilestonePlanning SET LastPlanningActionID = @ActionID WHERE MilestonePlanningID = @MilestonePlanningID; 

    --LOG 
    SELECT @Name = AN.ActionName FROM ActionName AN WHERE AN.ActionNameID = @ActionNameID 
    SET @log = 'Milestone['+CAST(@MilestonePlanningID AS VARCHAR(MAX))+'] : Last Action Changed To ' + @Name  
    EXEC master..xp_cmdshell @cmdtxt, no_output 

    SELECT @cmdtxt = 'echo ' + @log + ' >> c:\database_logs\'+DB_NAME(DB_ID())+'_'+CAST(@MilestonePlanningID AS VARCHAR(MAX))+'.txt' 
    SET @log = 'UPDATE MilestonePlanning SET LastPlanningActionID = '+CAST(@ActionID AS VARCHAR(MAX))+' WHERE MilestonePlanningID = ' + CAST(ISNULL(@MilestonePlanningID,0) AS VARCHAR(MAX)) 
    EXEC master..xp_cmdshell @cmdtxt, no_output 

    SELECT @cmdtxt = 'echo ' + @log + ' >> c:\database_logs\'+DB_NAME(DB_ID())+'_'+CAST(@MilestonePlanningID AS VARCHAR(MAX))+'.txt' 
    EXEC master..xp_cmdshell @cmdtxt, no_output 
    EXEC(@log) 
    END 

END 

이 트리거 모든 작업은, 그러나 때때로 업데이트 문이 자동으로 실패들이거나 결코 그러나 로그 파일이 생성됩니다, 발생하지

EDIT (테스트 목적으로 내가 무슨 일이 일어나고 있는지 볼 수있는 로그 파일 작성) : 나는 다음을 시도 을,하지만 여전히 작동하지 않습니다, MilestonePlanning 행이 업데이트됩니다 일부 하지 마세요

ALTER TRIGGER [dbo].[LastActionTrigger] on [dbo].[PlanningAction] 
AFTER INSERT AS 

BEGIN 


UPDATE MilestonePlanning SET LastPlanningActionID = i.ActionID 
FROM Inserted i 
WHERE MilestonePlanning.MilestonePlanningID = i.MilestonePlanningID AND i.ActionNameID NOT IN (10,11,12) 

END 

편집 : 트리거 근무 위, 주요 문제는 트리거가 발사 후 어떤 조치가 MilestonePlanning 업데이트 곳 뒤에 코드에서했다, 이것은 이전 LastPlanningActionID이

답변

2

귀하의 근본적인 결함이 보일 것입니다을 다시 것을 발생 트리거가 실행될 것으로 예상하는 경우 - - 이것은 이 아니며 SQL Server의 경우입니다. 대신, 트리거 화재 문 당 한 번 Inserted 의사 테이블과 Deleted 힘 (그리고 것입니다!이) 여러 행가 포함되어 있습니다.

테이블에 여러 개의 행이 포함될 수 있습니다.이 행 중 하나는 여기에서 선택됩니까?

SELECT @ActionID = i.ActionID, @ActionNameID = i.ActionNameID, @MilestonePlanningID = i.MilestonePlanningID 
FROM Inserted i 

정의되지 않은 - 당신이 Inserted에서 임의의 행의 값을 얻을 수 있습니다 - 다른 모든 행은

당신은 지식 Inserted의지와 전체 트리거를 다시 작성해야 ..... 무시됩니다 여러 행을 포함합니다! 세트 기반 작업으로 작업해야합니다. Inserted에 단 하나의 행만 있으면 안됩니다!

또한 : 난 강력하게 트리거에서 처리를 소모 언제든지 할 하지를 추천 할 것입니다 - 가장 확실히 xp_cmdshell 같은 외부 의존성을 호출하지 않습니다. 트리거는 실행중인 트랜잭션의 컨텍스트에서 실행되며 긴 처리가 있으면 해당 트랜잭션의 실행 시간이 연장됩니다. 방아쇠는 이되어야합니다. 민첩한과 많은 처리를하지 마십시오! 나는이 상황을 제대로 이해한다면

+0

그래서, 그때 –

+1

xp_cmdshell을 만 시도하고 문제점이 \t UPDATE MilestonePlanning SET LastPlanningActionID = i.ActionID \t FROM 같은 –

+0

뭔가를 알아 내기 위해 사용 된 커서 또는 무언가를 만드는 중 하나가 필요합니다 삽입 됨 \t 어디서 MilestonePlanning.MilestonePlanningID = i.MilestonePlanningID 테스트를하고 무슨 일이 일어나는가보기 –