在仅更新SQL Server 2008

时间:2015-05-04 19:19:51

标签: sql-server sql-server-2008 triggers updates

我有下表这个结构:

CREATE TABLE [dbo].[Tasks]
(
    [TasksID] [int] IDENTITY(1,1) NOT NULL,
    [CommitteeID] [int] NULL,
    [TransactionDateTime] [datetime2](7) NULL,
    [inspectionStatus] [nvarchar](50) NULL,
    [Latitude] [nvarchar](50) NULL,
    [Longitude] [nvarchar](50) NULL,
    [acceptanceState] [nvarchar](50) NULL,
    [comments] [nvarchar](350) NULL,
    [ScheduledDateTime] [datetime2](7) NULL,
)

我想要的是创建一个用当前日期时间更新[TransactionDateTime]的触发器,仅当列[acceptanceState]更新时才会这样。

我创建了以下触发器

CREATE TRIGGER [dbo].[TransactionDateUpdate]
ON [dbo].[Tasks]
AFTER UPDATE  
AS BEGIN
   UPDATE dbo.Tasks
   SET TransactionDateTime = GETDATE()
   FROM INSERTED i
   WHERE i.TasksID = Tasks.TasksID 
END

此触发器的问题是,它更新了列[TransactionDateTime],但是如果我对表中的任何列进行了更改,我想要的是仅在列{[TransactionDateTime]时更新[acceptanceState] {1}}已更改/更新。我可以找到任何帮助吗?如果更改/更新[TransactionDateTime],如何添加更新[acceptanceState]的条件?

我搜索了类似的问题,但我找不到完全相同的问题。

2 个答案:

答案 0 :(得分:12)

You just needed to add an IF UPDATE check and join deleted table in your trigger:

CREATE TRIGGER [dbo].[TransactionDateUpdate]
ON [dbo].[Tasks]
AFTER UPDATE  
AS 
BEGIN
   IF UPDATE(acceptanceState)  --add this line
   UPDATE dbo.Tasks
   SET TransactionDateTime = GETDATE()
   FROM INSERTED i
   JOIN DELETED d on i.TasksID = d.TasksID --add this line
   WHERE i.TasksID = Tasks.TasksID 
END

答案 1 :(得分:3)

执行此操作的最佳方法是比较InsertedDeleted伪表。在AFTER UPDATE触发器中,Deleted伪表包含旧值,而Inserted包含新值。因此,如果Deleted.acceptanceStateInserted.acceptanceState不同,则该列已更新。

所以你需要稍微扩展你的触发器:

CREATE TRIGGER [dbo].[TransactionDateUpdate]
ON [dbo].[Tasks]
AFTER UPDATE  
AS BEGIN
   UPDATE dbo.Tasks
   SET TransactionDateTime = GETDATE()
   FROM Inserted i
   INNER JOIN Deleted d ON i.TasksID = d.TasksID
   WHERE i.TasksID = Tasks.TasksID 
     AND i.acceptanceState <> d.acceptanceState
END