SQL Server触发特定列值

时间:2015-06-30 14:59:29

标签: sql sql-server sql-server-2008

我有一个名为Status的生产表,下面显示的列包括几个示例行:

Id  TaskOriginator  AssignedTo  Status
--------------------------------------
1   CANDYC  EBEKE0  Approved
2   UPOFA0  CANDYC  Approved
3   PKOOP0  EBEKE0  Approved
4   UPOFA0  PKOOP0  Approved
5   PKOOP0  RVDWE0  Completed
6   PKOOP0  RVDWE0  Completed
7   PKOOP0  RVDWE0  Completed
8   PKOOP0  RVDWE0  Completed
9   PKOOP0  RVDWE0  Completed
10  PKOOP0  RVDWE0  Completed

现在,当插入新行时,它会获得新状态,然后会发生操作并使用名称更新assignedTo列,现在我想在此assignedTo列上触发,如果状态为新,并且已分配给列的人员已更新为以下人员之一(例如FBOJE0ASWARTZEDEWAAL),则应通过触发器发送邮件。

如何在不锁定表格进行插入或其他进程更新的情况下,如何进行这样的触发?

2 个答案:

答案 0 :(得分:1)

嗯,触发器将始终运行,因此最小化从一开始就会执行的操作。在触发器中,检查列是否已更新:

create trigger trgTableIU on Table for insert , update
AS
BEGIN
        if update (assignedTo) 
        BEGIN
             select i.id,i.assignedto into #usethese from inserted i join deleted d on i.id=d.id and i.assignedto in ('FBOJE0','ASWARTZ','EDEWAAL') where i.status<>d.status and i.status not in ('new')
             if @@rowcount > 0
             BEGIN
                 --final mail stuff goes here 
                 --OR better yet, move to a working table that a job reviews every minute for records in working table
             END
        END
END

作为旁注,当我第一次开始时,触发器是惊人的,但随着时间的推移它们通常最终成为你的敌人。 (哦,这里只是另一个快速检查或处理......)。您应该尽可能避免使用,并且在使用时只需使用触发器中的最小过滤器设置快速查看标记,即另一个作业将通过并处理。

答案 1 :(得分:0)

评论时间有点长。

可以使用更新后触发器执行您想要的操作。

但是,我不鼓励你采取这种方法。听起来您对应用程序有一系列复杂的要求。相反,我建议你有一个更新的存储过程。然后,此存储过程可以执行您想要的所有逻辑 - 您根本不必担心锁定。

为什么我更喜欢存储过程而不是触发器?原因主要是可维护性。以下是一些:

  • 默认情况下,SQL Server Management Studio不会在表上编写触发器脚本。
  • 如果删除表(意外),则会删除所有触发器。重新创建表不会重新创建触发器。
  • 将触发器重新定义为INSTEAD OF触发器会产生严重的性能影响。
  • 存储过程可以执行许多其他操作,例如将错误消息返回给调用例程。
  • 随着逻辑变得复杂,触发器的限制可能会影响您的设计决策(例如没有动态SQL)和功能。