【问题标题】:Troubles with SQL TriggersSQL 触发器的问题
【发布时间】:2012-02-28 13:31:15
【问题描述】:

我对 SQL Server (2008 R2) 中的触发器有点陌生,我遇到了一个小问题。我有一个下表(为简洁起见省略了一些字段):

CREATE TABLE [dbo].[Task] (
    [TK_ID] [int] IDENTITY(1,1) NOT NULL,
    [TK_DateModified] [datetime] NULL,
    [TK_ModifiedBy] [int] NULL,
    [TK_DateCreated] [datetime] NULL,
    [TK_CreatedBy] [int] NULL,
    [TK_AssignedTo] [int] NULL)

我一共向表中添加了 3 个触发器:

触发器 1 正在创建记录(插入),它设置创建日期和创建记录的用户。

触发器 2 正在更新记录,它设置修改日期和修改记录的用户。

触发器 3 正在记录插入/更新,并设置为向 TK_AssignedTo 字段指定的用户发送电子邮件。

当我尝试插入记录时,它会向用户发送多封电子邮件。我最终收到了一封创建电子邮件和两封更新电子邮件。我希望插入从插入中击中触发器 1 和触发器 3,但我认为触发器 1 中“已创建”字段的更新是第二次触发触发器 3,并且因为触发器 1 导致字段更新它触发触发器 2 ,它会进行另一次更新并再次触发触发器 3。我尝试关闭数据库中的递归触发器以防止这种情况发生,但我认为这没有达到预期的效果,我尝试在触发器 3 中进行更改以防止在“创建”和“修改”字段时发送电子邮件被解雇了。这是目前触发器 3 的代码框架。

ALTER TRIGGER [dbo].[trig_Task_SendEmail] ON [dbo].[Task] FOR INSERT,UPDATE AS
IF (NOT UPDATE(TK_DateCreated)) AND (NOT UPDATE(TK_CreatedBy)) AND (NOT UPDATE(TK_DateModified)) AND (NOT UPDATE(TK_ModifiedBy))
BEGIN
  -- Coding to send email to user on changed tasks
END

在这种形式中,发送电子邮件的代码根本不会运行,即使在插入时也是如此。我认为 UPDATE(field) 函数不能像我希望的那样工作。有没有办法禁止更新这 4 个字段以触发另一个更新触发器或其他一些可行的选项,以仅让触发器 1 和 3 在插入时触发,而触发器 2 和 3 在更新时触发?

【问题讨论】:

  • 每当你插入一条记录时,基本上它都会创建一个魔术表,然后你可以从那里控制,你是否尝试过魔术表
  • 我能够进行一些小的更改并使其正常工作。感谢您的提示
  • 根据我下面的回答,如果您真的只想在插入/更新TK_AssignedTo 时发送通知电子邮件,您可能只想说IF UPDATE(TK_AssignedTo) 而不是处理所有那些... NOT UPDATE ... 条件。但我可能在那里做了一个无效的假设。

标签: tsql triggers


【解决方案1】:

如果您为列创建默认值,则可以删除您的第一个触发器:

...
[TK_DateCreated] [datetime] DEFAULT GETDATE(),
[TK_CreatedBy] [int] DEFAULT SUSER_SID()
...

我模拟了两个触发器(UPDATE 触发器和电子邮件触发器):

CREATE TRIGGER [dbo].[tgUpdatedRecord]
ON [dbo].[Task] FOR UPDATE
AS
    BEGIN
        UPDATE t
        SET t.TK_DateModified = GETDATE(),
            t.TK_ModifiedBy = SUSER_SID()
        FROM [dbo].[Task] t
        JOIN [inserted] i
            ON t.[TK_ID] = i.[TK_ID]
    END
GO

...和...

CREATE TRIGGER [dbo].[trig_Task_SendEmail]
ON [dbo].[Task] FOR INSERT, UPDATE
AS
    IF UPDATE(TK_AssignedTo) BEGIN
        PRINT 'Is this an email?'
    END
GO

这似乎符合您的预期。

【讨论】:

    猜你喜欢
    • 2011-08-06
    • 1970-01-01
    • 2020-12-24
    • 2020-12-15
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2011-11-02
    相关资源
    最近更新 更多