2017-02-16 25 views
1

我有我的桌子下面的Microsoft SQL Server觸發器:如何做一個SQL Server觸發器中的IF檢查

-- Insert statements for trigger here 
DECLARE @AssignmentUID uniqueidentifier; 
DECLARE @ResourceUID uniqueidentifier; 
DECLARE @ResourceName nvarchar(255); 
DECLARE @ResourceClaimsAccount nvarchar(255); 
DECLARE @ProjectUID uniqueidentifier; 
DECLARE @ProjectName nvarchar(255); 
DECLARE @ProjectUrl nvarchar(1000); 
DECLARE @TaskUID uniqueidentifier; 
DECLARE @TaskName nvarchar(255); 
DECLARE @TaskUrl nvarchar(1000); 
DECLARE @UserId nvarchar(255); 
DECLARE @PWAUrl nvarchar(255); 
DECLARE @sql varchar(8000) 

SELECT @AssignmentUID = INSERTED.AssignmentUID 
FROM INSERTED; 

SELECT   
    @TaskUID = MSP_EpmAssignment_UserView.TaskUID, 
    @TaskName = MSP_EpmTask_UserView.TaskName, 
    @ProjectUID = MSP_EpmAssignment_UserView.ProjectUID, 
    @ProjectName = MSP_EpmProject_UserView.ProjectName, 
    @ProjectUrl = MSP_EpmProject_UserView.ProjectWorkspaceInternalHRef, 
    @ResourceUID = MSP_EpmAssignment_UserView.ResourceUID, 
    @ResourceClaimsAccount = MSP_EpmResource_UserView.UserClaimsAccount, 
    @ResourceName = MSP_EpmResource_UserView.ResourceName 
FROM 
    MSP_EpmAssignment_UserView 
LEFT OUTER JOIN 
    MSP_EpmResource_UserView ON MSP_EpmAssignment_UserView.ResourceUID = MSP_EpmResource_UserView.ResourceUID 
LEFT OUTER JOIN 
    MSP_EpmProject_UserView ON MSP_EpmAssignment_UserView.ProjectUID = MSP_EpmProject_UserView.ProjectUID 
LEFT OUTER JOIN 
    MSP_EpmTask_UserView ON MSP_EpmAssignment_UserView.TaskUID = MSP_EpmTask_UserView.TaskUID 
WHERE 
    (MSP_EpmAssignment_UserView.AssignmentUID = @AssignmentUID); 

INSERT INTO tablename 
(ItemTitle, ParentName, ParentUrl, Loginname, SourceId, CreatedAt) 
VALUES (@TaskName, @ProjectName, @ProjectUrl, RIGHT(@ResourceClaimsAccount, CHARINDEX('\', REVERSE('\' + @ResourceClaimsAccount)) - 1), 1, GETDATE()); 

我如何檢查是否@AssignmentUID和@TaskUID執行INSERT前IS NOT NULL INTO聲明?是否還有可能優化此觸發器?

+3

你的觸發器有** MAJOR **缺陷,你似乎認爲它會被稱爲每行** ** - 這是**不是**的情況。觸發器將在每個語句**中觸發一次**,因此如果您的INSERT語句影響25行,您將觸發**觸發一次**,但是「插入」將分別包含25行。您的代碼在這25行中選擇哪一個? 'SELECT @AssignmentUID = INSERTED.AssignmentUID FROM INSERTED' - 它是非確定性的。你需要重寫你的觸發器來考慮這個問題! –

+0

這是一個INSERT觸發器。 INSERT觸發器也可以這樣嗎? – STORM

+0

***是!***絕對! *** SQL Server中的所有***觸發器在每個語句中都有**一次,並處理可能的多行! (例如,如果您基於另一個表中的「SELECT」插入到表中) –

回答

3

你需要寫你的觸發器在基於一套方式來處理該Inserted表可能包含多個行的事實。

試試這個代碼 - 它使用你的核心SELECT,並且INNER JOINInserted這個表上,你試圖在開始時抓住這個表。這將一次處理全部行,包含在Inserted表中 - 無循環,無遊標 - 不需要此類雜亂的代碼!

INSERT INTO tablename (ItemTitle, ParentName, ParentUrl, Loginname, SourceId, CreatedAt) 
SELECT   
    MSP_EpmTask_UserView.TaskName, 
    MSP_EpmProject_UserView.ProjectName, 
    MSP_EpmProject_UserView.ProjectWorkspaceInternalHRef, 
    RIGHT(MSP_EpmResource_UserView.UserClaimsAccount, CHARINDEX('\', REVERSE('\' + MSP_EpmResource_UserView.UserClaimsAccount)) - 1, 
    1, 
    SYSDATETIME() 
FROM 
    MSP_EpmAssignment_UserView 
INNER JOIN 
    Inserted i ON MSP_EpmAssignment_UserView.AssignmentUID = i.AssignmentUID 
LEFT OUTER JOIN 
    MSP_EpmResource_UserView ON MSP_EpmAssignment_UserView.ResourceUID = MSP_EpmResource_UserView.ResourceUID 
LEFT OUTER JOIN 
    MSP_EpmProject_UserView ON MSP_EpmAssignment_UserView.ProjectUID = MSP_EpmProject_UserView.ProjectUID 
LEFT OUTER JOIN 
    MSP_EpmTask_UserView ON MSP_EpmAssignment_UserView.TaskUID = MSP_EpmTask_UserView.TaskUID 
1
IF (@AssignmentUID IS NOT NULL AND @TaskUID IS NOT NULL) 
BEGIN 
    ... 
END