Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在SQL Server 2008中仅更新同一表中的特定列后,更新触发器中的一列_Sql Server_Sql Server 2008_Triggers_Updates - Fatal编程技术网

Sql server 在SQL Server 2008中仅更新同一表中的特定列后,更新触发器中的一列

Sql server 在SQL Server 2008中仅更新同一表中的特定列后,更新触发器中的一列,sql-server,sql-server-2008,triggers,updates,Sql Server,Sql Server 2008,Triggers,Updates,我的下表采用了这种结构: 创建表[dbo].[Tasks] ( [TasksID][int]标识(1,1)不为空, [CommitteeID][int]NULL, [TransactionDateTime][datetime2](7)空, [inspectionStatus][nvarchar](50)空, [纬度][nvarchar](50)空, [经度][nvarchar](50)空, [acceptanceState][nvarchar](50)无效, [评论][nvarchar](350

我的下表采用了这种结构:

创建表[dbo].[Tasks]
(
[TasksID][int]标识(1,1)不为空,
[CommitteeID][int]NULL,
[TransactionDateTime][datetime2](7)空,
[inspectionStatus][nvarchar](50)空,
[纬度][nvarchar](50)空,
[经度][nvarchar](50)空,
[acceptanceState][nvarchar](50)无效,
[评论][nvarchar](350)无效,
[ScheduledDateTime][datetime2](7)空,
)
我想要的是创建一个触发器,仅当列
[acceptanceState]
更新时,才使用当前日期时间更新
[TransactionDateTime]

我创建了以下触发器

此触发器的问题是,它更新列
[TransactionDateTime]
,但是如果我对表中的任何列进行了更改,那么我只想在列
[acceptanceState]
更改/更新时更新
[TransactionDateTime]
。我能找人帮忙吗?仅当更改/更新了
[acceptanceState]
时,如何添加更新
[TransactionDateTime]
的条件


我搜索了很多类似的问题,但没有找到完全相同的问题。

您只需要在触发器中添加一个IF UPDATE check和join deleted表:

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

最好的方法是比较
插入的
删除的
伪表。在更新后的
触发器中,已删除的
伪表包含旧值,而插入的
包含新值。因此,如果
Deleted.acceptanceState
Inserted.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
创建触发器[dbo]。[TransactionDateUpdate]
关于[dbo].[Tasks]
更新后
作为开始
更新dbo.Tasks
设置TransactionDateTime=GETDATE()
从插入i
i.TasksID=d.TasksID上的内部联接已删除d
其中i.TasksID=Tasks.TasksID
和i.接受状态d.接受状态
结束

您必须将删除的表添加到查询中,并检查插入的值和删除的值是否不同。此外,我相信SQL Server有一个函数“IF UPDATE(ColumnName)”,可以让您检查某一列是否已更新。@TabAlleman:这将如何处理多行更新,尽管?@TabAlleman使用更新(ColumnName)的一个问题是,如果更新中包含该列,则返回true。它不考虑实际值。换句话说,即使新值和旧值相同,它也会返回true。true,@SeanLange,if UPDATE()可用于在列不可能发生更改时避免处理器执行查询,但它完全如您所说,如果该列包含在UPDATE语句中,则返回true,不管值是否改变。很高兴听到!如果你能帮我一个忙,并将其标记为已接受的答案,那就太好了!谢谢我做了标记,对不起,我是新来的,我以前不知道这个标记,不用担心!:)我每天都在这里学到新东西!再次感谢!仅了解此功能以检查更新的列。对我来说是新的!比起公认的答案,我更喜欢这个。但是
WHERE
子句不也应该包括
null
<代码>和(i.acceptanceState d.acceptanceState或d.acceptanceState为空且i.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