2012-08-03 90 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表中找不到对应的行。