SQL - 更新后触发器 - 如何在列值更改为特定值时添加时间戳

时间:2015-11-08 07:48:58

标签: sql sql-server triggers

我想创建一个Trigger来更新列

dbo.tbl_dispatching.Actual_Pickup_Time
当下面的列更新为5

时,带有时间戳的

dbo.tbl_dispatching.Status_ID = "5" 

并更新

dbo.tbl_dispatching.Actual_Delivery_Time 
当下面的列更新为8

时,带有时间戳的

dbo.tbl_dispatching.Status_ID = "8"

到目前为止我已经这样做了,不知道如何完成它:

CREATE TRIGGER Delay_Timestamp ON [dbo].[tbl_dispatching] 
FOR UPDATE
AS
    declare @DispatchingID int; --Primery Key of Dispatching_ID
    declare @Statusid int;
    declare @Actual_Pickup_Time datetime;
    declare @Actual_Delivery_Time datetime;
    declare @audit_action varchar(100);

select @DispatchingID=i.dispatching_id from inserted i; --Primery Key of Dispatching_ID
select @Statusid=i.Status_ID from inserted i; 
select @Actual_Pickup_Time=i.Actual_Pickup_Time from inserted i; 
select @Actual_Delivery_Time=i.Actual_Delivery_Time from inserted i;   

if @StatusID = (5)
    set @Actual_Pickup_Time=GETDATE();
if  @StatusID = (8)
    set @Actual_Delivery_Time=GETDATE();

update set tbl_Dispatching(Actual_Pickup_Time,Actual_Delivery_Time) 
values (@Actual_Pickup_Time,@Actual_Delivery_Time) where dispatching_id = @DispatchingID
go

这会有用吗?

1 个答案:

答案 0 :(得分:1)

您的根本缺陷是,您似乎希望触发器每行一次 - 这在SQL Server中是 NOT 。相反,触发器会在每个语句时触发,并且伪表InsertedDeleted可能包含多行

在这种情况下,这个作业

select @Statusid=i.Status_ID from inserted i; 

将从Inserted表中选择一行任意行忽略所有其他行 - 通常不是您想要的。

您需要以基于集合的方式重写触发器 - 不要指望InsertedDeleted只包含一行 - 他们不会!

您需要使用以下代码:

CREATE TRIGGER Delay_Timestamp ON [dbo].[tbl_dispatching] 
FOR UPDATE
AS
    -- Update Actual_Pickup_Time if "Status_ID" has changed to 5
    UPDATE disp
    SET Actual_Pickup_Time = SYSDATETIME()
    FROM dbo.tbl_Dispatching disp
    INNER JOIN Inserted i ON i.DispatchId = disp.DispatchId  -- use PRIMARY KEY of table!
    INNER JOIN Deleted d ON d.DispatchId = disp.DispatchId  -- use PRIMARY KEY of table!
    WHERE
          i.Status_ID = 5         -- new value is 5 
          AND d.Status_ID <> 5    -- old value was NOT 5

    -- Update Actual_Delivery_Time if "Status_ID" has changed to 8
    UPDATE disp
    SET Actual_Delivery_Time = SYSDATETIME()
    FROM dbo.tbl_Dispatching disp
    INNER JOIN Inserted i ON i.DispatchId = disp.DispatchId  -- use PRIMARY KEY of table!
    INNER JOIN Deleted d ON d.DispatchId = disp.DispatchId   -- use PRIMARY KEY of table!
    WHERE
          i.Status_ID = 8         -- new value is 8 
          AND d.Status_ID <> 8    -- old value was NOT 8