SQL Server更新后触发器不工作
我有以下结构的模式; 在MPRMain表中,状态可以是1验证、2取消和3结束。我正在尝试这样做,例如当有人将MPRMain中的状态更新为2Cancel时。我想将MPRDetail表的状态更新为0表示禁用,1表示启用。 所以,我试图为它创建一个触发器,看起来像这样SQL Server更新后触发器不工作,sql,sql-server,tsql,triggers,Sql,Sql Server,Tsql,Triggers,我有以下结构的模式; 在MPRMain表中,状态可以是1验证、2取消和3结束。我正在尝试这样做,例如当有人将MPRMain中的状态更新为2Cancel时。我想将MPRDetail表的状态更新为0表示禁用,1表示启用。 所以,我试图为它创建一个触发器,看起来像这样 Alter Trigger Inventory.MprMainUpdate ON Inventory.MPRMain AFTER UPDATE AS BEGIN declare @status as int;
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
但是,当我尝试将MPRMain的状态设置为2 Cancel From 1 Aprove时,在MPRDetail表中看不到任何更改。这会将MPRDeail状态更新为0 0以禁用。由于插入的行可以包含多行,因此需要使用基于集合的方法写入触发器:
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
因此,基本上您需要根据MPRId列将实际数据表与插入的伪表连接起来,并将基表中的所有行更新为Status=0,其中Inserted.Status=2
好的-我来看看:假设UPDATE语句更新了四行,那么Inserted在触发器中可能是这样的:
MPRId MprNo Date DepartmentId Status
1 42 .. ....... 1
2 43 .. ....... 2
7 33 .. ....... 7
9 41 .. ....... 2
现在,根据mprdeail表连接这组数据,并且只选择那些状态为Inserted为2的行-因此
MPRId Status MPRDetail.Status (other columns of MPRDetail for those values)
2 2 4 .....................................
9 2 5 .....................................
因此,在本例中,MPRDetail中的这两行在触发器中的状态都将更新为0-不会触及任何其他行
这能让事情更清楚一点吗?如果没有:你被困在哪里了,什么仍然是神奇的,因此你不清楚?你的第一个问题是,你错误地假设触发器每行调用一次——事实并非如此。每个语句调用一次,插入的表可以也可以!包含多行-因此,使用set@status=select status FROM inserted;-这是没有定义的。您需要重写触发器,以考虑插入和删除的触发器将包含多行!您需要使用基于集合的方法来处理这些问题approach@marc_s,如果您有任何例子,我们将不胜感激。我以前从未使用过触发器。我是否应该删除前3行,即ifcondition@DotNetDreamer:是-因为使用我的触发器时完全不需要这些行-该代码检查相同的条件抱歉,它工作得很好。我能有一个更具描述性的答案或一个可以帮助我的链接吗?现在一切都清楚了。亲爱的:这在MySQL中很容易,而在SQL Server中很难做到。