【问题标题】:SQL Server trigger on a field that's updatedSQL Server 在更新的字段上触发
【发布时间】:2012-08-01 00:44:52
【问题描述】:

我有以下触发器:

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 插入时。我在这里做错了什么:

【问题讨论】:

  • inserteddeleted 是表,因此它们可以表示集合操作的结果。假设触发器总是只包含一行而设计触发器通常是一个糟糕的计划。
  • 一般来说:将尽可能少的逻辑放入您的触发器中。它们出乎意料地开火,比预期的更频繁,而且你无法控制它们的执行。我会从不将任何处理逻辑放入触发器中。您最多应该在另一个表中插入需要发送电子邮件的提醒 - 但不要在触发器中自己执行此操作。相反,有一个单独的 SQL Server 作业定期检查该表,然后从您的主应用程序异步发送这些电子邮件。

标签: sql sql-server sql-server-2005 triggers


【解决方案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 表中没有找到对应的行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-01
    • 2016-11-03
    • 2010-11-18
    • 1970-01-01
    • 2020-03-24
    • 2011-06-03
    • 1970-01-01
    • 2015-01-20
    相关资源
    最近更新 更多