更新触发器不在 where 子句中使用日期导致更新具有相同键 ID 的所有记录,而不仅仅是具有当前日期的记录

Update Trigger not using date in where clause causing all records with same key id to be updated instead of just the ones with the current date

我有一个库存跟踪应用程序,我也在跟踪每个位置的库存变化。库存项目可以位于多个位置。这是通过拥有一个跟踪数据库并在我的库存 table 上使用触发器来实现的。如果我更改一次项目的数量,触发器将按预期工作。如果我返回并再次更改同一位置的数量,则该位置(仅)的所有数量都将更新为相同的数量。这是我的触发器:

INSERT tblInvTracking(keyProductID, fldLocationId, fldLastPhysical, fldQuantity, fldInventoryChange, fldNewQuantity)
    SELECT D.keyProductID, I.fldLocationID, D.fldLastPhysical, d.fldQuantity, i.fldLastPhysical, i.fldQuantity
    FROM DELETED D
    JOIN INSERTED I ON D.keyProductID = I.keyProductID
    WHERE D.fldLastPhysical <> i.fldLastPhysical AND d.fldLocationID = i.fldLocationID;

UPDATE tblInvTracking 
    SET fldNewQuantity = (SELECT inserted.fldQuantity FROM inserted)
    FROM deleted d
    JOIN inserted i ON D.keyProductID = I.keyProductID
    WHERE d.fldLastPhysical = i.fldLastPhysical AND tblInvTracking.keyProductID = i.keyProductID AND tblInvTracking.fldLocationID = i.fldLocationID;

由于我的 INSERT 语句被正确执行,我知道 WHERE 子句有效。问题一定出在我的 UPDATE WHERE 子句中,该子句似乎忽略了 d.fldLastPhysical = i.fldLastPhyiscal.

注意:触发器是我的库存 table 的 'ON UPDATE' 触发器。当我在特定日期更改特定位置的特定零件的数量时,触发器将在跟踪 table 中插入一条新记录。如果随后更改了数量,则不会在该日期在该位置的该零件上创建新记录。这就是 where 子句在插入语句中的作用,并且有效。

我想要发生的是,如果数量在同一日期在同一位置发生变化,则跟踪 table 中的数量会在该日期更新。 似乎 D.fldLastPhysical <> i.fldLastPhysical 有效,但 d.fldLastPhysical = i.fldlastPhysical 无效。针对所有日期更新特定位置的单个部分。

如果不清楚,我深表歉意,但我必须了解您的回复并处理结果。因此,更新语句中的 where 子句无法正常工作。

谢谢

您犯了一个经典错误 - 假设 UPDATE 触发器中的 Inserted 伪 table 只包含一行 - 通常 不是这种情况!

看这段代码:

UPDATE tblInvTracking 
SET fldNewQuantity = (SELECT inserted.fldQuantity FROM inserted)
                     ********************************************
FROM deleted d
JOIN inserted i ON D.keyProductID = I.keyProductID

如果您的 UPDATE 操作影响 10 行 - 您认为其中哪一行将用于获取 inserted.fldQuantity 值?它是 非确定性的 - 一个将被使用,所有其他的将被忽略。这是双重悲伤,因为您已经以适当的set-based方式在查询中访问InsertedDeleted

那你为什么不直接用这个呢?

UPDATE it
SET fldNewQuantity = i.fldQuantity 
FROM inserted i 
INNER JOIN tblInvTracking it ON it.keyProductID = i.keyProductID 
                             AND it.fldLocationID = i.fldLocationID;

既然您没有引用 Deleted 伪 table 中的任何内容 - 为什么还要将其包含在 UPDATE 中?另外:在适当的 INNER JOIN 中定义 InsertedtblInvTracking 之间的连接条件,而不是使用 WHERE 子句 ...

我修改了 where 子句,以便 d.fldLastPhysical 使用解决问题的今天的日期。显然,i.fldLastPhysical 发生了一些事情导致我最初的问题。

感谢马克的反馈。