2012-08-03 127 views
0

我有以下觸發:SQL服務器觸發

BEGIN 
DECLARE @email varchar(200) 
DECLARE @jobcode int 
DECLARE @status char(1) 

DECLARE @emaild varchar(200) 
DECLARE @jobcoded int 
DECLARE @statusd char(1) 

SET @statusd = NULL 

SELECT @status = z.status, @email = p.EMail, @jobcode = z.jobID 
    FROM zipoutfiles z 
    INNER JOIN inserted AS i ON z.jobID = i.jobID 
    INNER JOIN PS_LoginUser AS p ON z.UserID = p.UserID 

SELECT @statusd = z.status, @emaild = p.EMail, @jobcoded = z.jobID 
    FROM zipoutfiles z 
    INNER JOIN deleted AS d ON z.jobID = d.jobID 
    INNER JOIN PS_LoginUser AS p ON z.UserID = p.UserID 
    WHERE d.jobID = @jobcode 


IF ((@status = 'D' AND @statusd = 'R') OR (@status = 'D' AND @statusd = 'E')) 
BEGIN 
    EXEC SendMail @email, @jobcode 
END 
END 

我希望能夠當狀態從E增大到d或R到d運行sendmail,但它不是d至d(如果它被再次更新),並且當它被插入爲D.我在做什麼錯在這裏:

+2

'inserted'和'deleted'是表,以便它們可以表示設置操作的結果。假設它們總是包含一行,設計一個觸發器通常是一個糟糕的計劃。 – HABO 2012-08-03 01:11:01

+1

一般來說:將**儘可能少的邏輯**放入觸發器中。他們意外地開火,比預期的更頻繁,你無法控制他們的執行。我將**從不**將任何處理邏輯放入觸發器中。您最多可以在另一個表格中插入提醒,以便發送電子郵件 - 但不要在觸發器內自行完成。相反,有一個單獨的SQL Server作業定期檢查該表,然後與主應用程序異步發送這些電子郵件。 – 2012-08-03 04:49:34

回答

1

不知道你的表模式是什麼,但是這可能讓你所有適當的電子郵件:

select p.EMail as Email, z.JobId as JobCode 
    from ZipOutFiles as ZOF inner join 
    inserted as i on i.JobId = ZOF.JobId inner join 
    PS_LoginUser as PLU on PLU.UserId = ZOF.UserId left outer join 
    deleted as d on d.JobId = ZOF.JobId 
    where 
     (d.Status = 'E' and i.Status = 'D') or -- E -> D. 
     (d.Status = 'R' and i.Status = 'D') or -- R -> D. 
     (d.Status is NULL and i.Status = 'D') -- Inserted D. 

我假設你不是真的更新JobId。如果是這樣,你如何匹配前後行?

還假定Status不能是NULL。如果是這樣,則需要修改最後一個條件以正確檢測deleted表中找不到對應的行。