为什么在更新触发器之后将SQL UPDATE()函数与Inserted table一起使用不能正常工作?

时间:2018-10-12 13:12:33

标签: sql-server tsql sql-server-2008 database-trigger

我在这里找到了两个类似的问题,我曾尝试解决此问题,但似乎没有任何效果。 因此,基本上,我有一个Pallet表,当Loaded字段的值更改为<>或<>更改为 NULL 时,我需要更改Status字段,并且Status也有所不同。触发器基本上什么也不做。所以,我有:

ALTER TRIGGER [dbo].[TR_Status_Change]
   ON [dbo].[Pallet]
   AFTER UPDATE
AS BEGIN

    SET NOCOUNT ON;
    IF UPDATE (Loaded)
    BEGIN
        UPDATE [Pallet] 
        SET PStatus = 3
        FROM [Pallet] P 
        INNER JOIN Inserted I ON P.ID = I.ID
        WHERE P.PStatus <> 3
            AND P.Loaded <> I.Loaded
            AND I.Loaded IS NOT NULL
    END
END

其中ID是主键。行值如下:

before update: Loaded = NULL, Status = 1

after: Loaded = 'somevalue' and Status remains = 1

expected: Status = 3

谢谢。

2 个答案:

答案 0 :(得分:3)

“与NULL相比的事物”比较始终为假,因此失败

AND P.Loaded <> I.Loaded

尝试一下。您还需要“已加载”的“之前”和“之后”值

UPDATE [Pallet] 
    SET PStatus = 3
    FROM [Pallet] P 
    INNER JOIN Deleted D ON P.ID = D.ID
    INNER JOIN Inserted I ON P.ID = I.ID
    WHERE P.PStatus <> 3
        AND NOT EXISTS (SELECT I.Loaded INTERSECT SELECT D.Loaded)
        AND I.Loaded IS NOT NULL

INTERSECT在内部进行“不同于”比较,而不是相等。如果它们不同,则相交不给出任何行,因此NOT EXISTS给出true

有关INTERSECT和EXCEPT的更多信息,请在这里Why does EXCEPT exist in T-SQL?

查看我的回答

答案 1 :(得分:0)

这是东西: P.Loaded <> I.Loaded

这永远不会是正确的,因为您将更新后的表数据([Pallet P])与....更新后的表数据(插入I)进行比较。

我认为您想将“插入的I”更改为已删除的表,该表包含更新操作之前的值。