仅在修改列时才触发SQL更新

Wal*_*ong 93 sql sql-server triggers

通过查看其他示例,我提出了以下内容,但它似乎没有按照我的意愿工作:我希望它只更新已修改的信息,如果QtyToRepair值已更新...但它不会那.

如果我注释掉了哪里,则在每种情况下都会更新修改后的信息.正如我所说的其他例子让我变得乐观.任何线索都表示赞赏.谢谢.

沃尔特

ALTER TRIGGER [dbo].[tr_SCHEDULE_Modified]
   ON [dbo].[SCHEDULE]
   AFTER UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    UPDATE SCHEDULE SET modified = GETDATE()
        , ModifiedUser = SUSER_NAME()
        , ModifiedHost = HOST_NAME()
    FROM SCHEDULE S
    INNER JOIN Inserted I on S.OrderNo = I.OrderNo and S.PartNumber = I.PartNumber
    WHERE S.QtyToRepair <> I.QtyToRepair
END
Run Code Online (Sandbox Code Playgroud)

meh*_*tfi 120

你的问题有两种方式:

1-在Trigger中使用Update命令.

ALTER TRIGGER [dbo].[tr_SCHEDULE_Modified]
   ON [dbo].[SCHEDULE]
   AFTER UPDATE
AS BEGIN
    SET NOCOUNT ON;
    IF UPDATE (QtyToRepair) 
    BEGIN
        UPDATE SCHEDULE 
        SET modified = GETDATE()
           , ModifiedUser = SUSER_NAME()
           , ModifiedHost = HOST_NAME()
        FROM SCHEDULE S INNER JOIN Inserted I 
        ON S.OrderNo = I.OrderNo and S.PartNumber = I.PartNumber
        WHERE S.QtyToRepair <> I.QtyToRepair
    END 
END
Run Code Online (Sandbox Code Playgroud)

2-使用Inserted table和deleted table之间的Join

ALTER TRIGGER [dbo].[tr_SCHEDULE_Modified]
   ON [dbo].[SCHEDULE]
   AFTER UPDATE
AS BEGIN
    SET NOCOUNT ON;    

    UPDATE SCHEDULE 
    SET modified = GETDATE()
       , ModifiedUser = SUSER_NAME()
       , ModifiedHost = HOST_NAME()
    FROM SCHEDULE S 
    INNER JOIN Inserted I ON S.OrderNo = I.OrderNo and S.PartNumber = I.PartNumber
    INNER JOIN Deleted D ON S.OrderNo = D.OrderNo and S.PartNumber = D.PartNumber                  
    WHERE S.QtyToRepair <> I.QtyToRepair
    AND D.QtyToRepair <> I.QtyToRepair
END
Run Code Online (Sandbox Code Playgroud)

当您对表使用update命令SCHEDULE并将Set QtyToRepairColumn 设置为新值时,如果新值等于一行或多行中的旧值,则解决方案1将更新Schedule表中的所有更新行,但解决方案2更新仅计划旧值不等于new的行值.

  • 方法#2更好,如果你不希望你的触发器被激活,如果列被更改为相同的值. (7认同)
  • 我想我可能遗漏了一些东西 - 但方法 #1 不起作用,因为这是 *after* 更新,所以当前行将始终与插入行具有相同的值。如果您在更新后使用,您*必须*加入删除 (3认同)
  • @Rob"IF UPDATE"语句正在调用一个过程,该过程可以访问作为查询一部分更新的列列列表,因此不需要知道以前的值.(我们刚刚在我们的环境中遇到过这种情况,并确认"IF UPDATE"无论"更新后"条款如何都被尊重) (3认同)
  • 为什么在第二个查询中加入“插入”表?它应该与表本身相同,不是吗? (2认同)

Wal*_*ong 19

fyi我最终得到的代码:

IF UPDATE (QtyToRepair)
    begin
        INSERT INTO tmpQtyToRepairChanges (OrderNo, PartNumber, ModifiedDate, ModifiedUser, ModifiedHost, QtyToRepairOld, QtyToRepairNew)
        SELECT S.OrderNo, S.PartNumber, GETDATE(), SUSER_NAME(), HOST_NAME(), D.QtyToRepair, I.QtyToRepair FROM SCHEDULE S
        INNER JOIN Inserted I ON S.OrderNo = I.OrderNo and S.PartNumber = I.PartNumber
        INNER JOIN Deleted D ON S.OrderNo = D.OrderNo and S.PartNumber = D.PartNumber 
        WHERE I.QtyToRepair <> D.QtyToRepair
end
Run Code Online (Sandbox Code Playgroud)


hgu*_*yan 12

人们应该检查一下是否QtyToRepair更新.

ALTER TRIGGER [dbo].[tr_SCHEDULE_Modified]
   ON [dbo].[SCHEDULE]
   AFTER UPDATE
AS 
BEGIN
SET NOCOUNT ON;
    IF UPDATE (QtyToRepair) 
    BEGIN
        UPDATE SCHEDULE 
        SET modified = GETDATE()
           , ModifiedUser = SUSER_NAME()
           , ModifiedHost = HOST_NAME()
        FROM SCHEDULE S INNER JOIN Inserted I 
            ON S.OrderNo = I.OrderNo and S.PartNumber =    I.PartNumber
        WHERE S.QtyToRepair <> I.QtyToRepair
    END
END
Run Code Online (Sandbox Code Playgroud)


Car*_*ara 5

您想要执行以下操作:

ALTER TRIGGER [dbo].[tr_SCHEDULE_Modified]
   ON [dbo].[SCHEDULE]
   AFTER UPDATE
AS 
BEGIN
SET NOCOUNT ON;

    IF (UPDATE(QtyToRepair))
    BEGIN
        UPDATE SCHEDULE SET modified = GETDATE()
            , ModifiedUser = SUSER_NAME()
            , ModifiedHost = HOST_NAME()
        FROM SCHEDULE S
        INNER JOIN Inserted I ON S.OrderNo = I.OrderNo AND S.PartNumber = I.PartNumber
        WHERE S.QtyToRepair <> I.QtyToRepair
    END
END
Run Code Online (Sandbox Code Playgroud)

请注意,无论值是否相同,每次更新列时都会触发此触发器.