2014-11-05 25 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 

我們的系統的工作原理與播放暫停芬蘭和其他行動,所有的行動,他們與這個觸發所有的工作,但有時候更新語句自動失效或從來沒有發生,但日誌文件被創建(爲了測試的目的,我寫了日誌文件,看看發生了什麼)

編輯: 我試過以下,但仍然無效,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中的情況。相反,觸發器觸發每條語句一次,假表InsertedDeleted力量(和會!)包含多行

鑑於該表可能包含多行 - 您期望在此處選擇哪一個?

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

它是不確定的 - 你可能會在Inserted從任意行中的值 - 和所有其他行將被忽略.....

您需要用知識InsertedWILL重寫整個觸發包含多行!您需要使用基於集合的操作 - 不要指望Inserted中只有一行!

另外:我強烈建議不是在觸發器中做任何耗時的處理 - 絕對不會調用像xp_cmdshell這樣的外部依賴項。觸發器在正在運行的事務的上下文中執行,任何冗長的處理都將延長該事務的執行時間。觸發器應該是真的很靈活而不是做很多處理!

+0

所以,如果我理解正確的這個,那麼我要麼需要創建 – 2014-11-05 10:19:17

+1

xp_cmdshell的僅用於嘗試並找出問題 – 2014-11-05 10:21:48

+0

像這樣的事情 \t UPDATE MilestonePlanning SET LastPlanningActionID = i.ActionID \t從遊標或東西插入我 \t哪裏MilestonePlanning.MilestonePlanningID = i.MilestonePlanningID 去測試,看看會發生什麼 – 2014-11-05 10:26:06