更新后的SQL Server触发器不起作用

时间:2013-06-17 10:58:11

标签: sql sql-server tsql triggers

我有以下结构的架构; enter image description here
MPRMain表中,Status可以是 1(Aprove),2(取消)和3(待处理)。我正在尝试做类似这样的事情,例如当有人将Status(在MPRMain中)更新为 2(取消)时。我想将Status表的MPRDetail更新为 0(0表示禁用,1表示启用)
所以,我试图为它创建一个看起来像这样的触发器;

Alter Trigger Inventory.MprMainUpdate
    ON Inventory.MPRMain
    AFTER UPDATE
AS
BEGIN 

    declare @status as int;
    set @status = (SELECT Status FROM inserted);
    if(@status=2)
    BEGIN
        UPDATE Inventory.MPRDetail
        SET Status = 0   -- update the status to canceled
        WHERE MPRId = (select MPRId from inserted);
    END

END

但是,当我尝试将Status的{​​{1}}设置为 2(取消)来自 1(Aprove)时,我不会看不到MPRMain表中的任何变化。这应该将MPRDetail状态更新为0(0表示禁用)。

1 个答案:

答案 0 :(得分:2)

由于Inserted可以包含多行,因此您需要使用基于集合的方法编写触发器:

ALTER TRIGGER Inventory.MprMainUpdate
    ON Inventory.MPRMain AFTER UPDATE
AS
BEGIN 
  UPDATE Inventory.MPRDetail
  SET Status = 0
  FROM Inserted i
  WHERE i.Status = 2 AND Inventory.MPRDetail.MPRId = i.MPRId;
END

所以基本上你需要根据Inserted列对MPRId伪表加入你的实际数据表,并将基表中的所有行更新为Status = 0 {{1} }}

好的 - 我来了:假设您的Inserted.Status = 2语句更新了四行,那么UPDATE可能会在您的触发器中显示如下:

Inserted

现在,您针对MPRId MprNo Date DepartmentId Status 1 42 .. ....... 1 2 43 .. ....... 2 7 33 .. ....... 7 9 41 .. ....... 2 表格JOIN这组数据,并且您只选择MPRDetailStatus为2的那些行 - 所以你得到了

Inserted

所以在这种情况下,MPRId Status MPRDetail.Status (other columns of MPRDetail for those values) 2 2 4 ..................................... 9 2 5 ..................................... 中的那些行都会在触发器内将MPRDetail更新为0 - 不会触及任何其他行。

这会让事情变得更清晰吗?如果不是:你在哪里被困,什么仍然是“神奇的”,因此你不清楚?