【发布时间】:2021-09-08 20:13:33
【问题描述】:
当“工作状态”为“完成”时,我将日期添加到 SQL 的列中,但我的问题是,当我在软件中再次打开并保存相同的作业时,它会运行触发器并再次更改日期到一个我不想要的新值。
我希望触发器仅在“工作状态”值不是“已完成”时运行。
GO
/****** Object: Trigger [dbo].[TRJCD_JOBREQUEST] Script Date: 06/25/2021 15:49:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[TRJCD_JOBREQUEST] ON [dbo].[TBL_JOBREQUEST]
AFTER UPDATE,INSERT
AS
if (Update (workstatus))
begin
DECLARE @Jobcompletiondate datetime
DECLARE @workstatus VARCHAR(15)
DECLARE @jobid int
select @workstatus = workstatus from inserted
select @jobid = jobid from inserted
select @Jobcompletiondate = GETDATE()
begin
if @workstatus='Completed'
update TBL_JOBREQUEST set JobCompDate=@Jobcompletiondate where jobid = @jobid
end
end
【问题讨论】:
-
触发器是高度特定于供应商的 - 所以请添加标签以指定您使用的是
mysql、postgresql、sql-server、oracle还是db2- 或者完全是别的东西。 -
您的触发器有一个all too common issue
-
触发器在执行指定语句时运行,而不是在您想要它运行时运行。您可以使用
deleted和inserted来确定特定列的before 和after 值,并决定在触发器中执行什么操作。请注意,update()function 返回true,无论列的值是否已更改,例如update Foo set Bar = 42 where Bar = 42;将导致Update( Bar )成为true。 -
IF UPDATE() 不符合您的想法。如果它针对工作状态列中没有实际更改的行运行,那么您有一个有缺陷的应用程序正在以低效的方式更新行。修复两者。如果您的代码必须仅在列更改时运行,则需要比较旧值和新值。
-
感谢@HABO。我不是 sql 专家。你能编辑我的代码来比较旧的新值吗?我只想在“工作状态”的现有值为“待定”且新值为“已完成”时更新“JobCompDate”列中的日期。我试过这个语句,但它不起作用 [update TBL_JOBREQUEST set JobCompDate=(at)Jobcompletiondate where jobid = (at)jobid and workstatus'Completed']
标签: sql-server tsql triggers