Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server更新后触发器不工作_Sql_Sql Server_Tsql_Triggers - Fatal编程技术网

SQL Server更新后触发器不工作

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;

我有以下结构的模式; 在MPRMain表中,状态可以是1验证、2取消和3结束。我正在尝试这样做,例如当有人将MPRMain中的状态更新为2Cancel时。我想将MPRDetail表的状态更新为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
但是,当我尝试将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中很难做到。