当列值更改时触发 SQL

Fire SQL Trigger When Column Value Changes

当 'workstatus' 为 'completed' 时,我将日期添加到 SQL 的列中,但我的问题是,当我在软件中再次打开并保存相同的作业时,它 运行 触发并再次将日期更改为我不想要的新值。

只有当 'workstatus' 值不是 'completed' 时,我才希望触发器为 运行。

    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

请注意,我没有你的数据集,所以我无法测试触发器,但是,根据你在问题中提供的内容,我相信这就是你正在寻找的答案:

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 @currentworkstatus VARCHAR(15)
DECLARE @oldworkstatus VARCHAR(15)
DECLARE @jobid int


select @oldworkstatus = workstatus from deleted
select @currentworkstatus = workstatus from inserted
select @jobid = jobid from inserted
select @Jobcompletiondate = GETDATE() 

begin

if @currentworkstatus='Completed' and @oldworkstatus <> 'Completed'


    update TBL_JOBREQUEST set JobCompDate=@Jobcompletiondate where jobid = @jobid 
end
end

您需要检查已删除的 workstatus 是否不等于 Completed,然后才应触发触发器。

以下是您应该如何构建触发器。

无需为变量分配任何值,触发器在每个 batch 中触发一次,并且始终对更新行的 set 进行操作.

如果您将状态更新为已完成,您需要检查它当前是否已完成,如果您想要保留第一个 JobCompDate,即使之后状态被修改,只需使用 case 表达式来仅更新当前为 NULL 的列。

create or alter trigger [dbo].[TRJCD_JOBREQUEST] on [dbo].[TBL_JOBREQUEST] 
after update,insert
as
if @@RowCount=0 return

set nocount on
if Update (workstatus)
begin

    update t set
        t.JobCompDate=case when t.JobCompDate is null then GetDate() else t.JobCompDate end
    from inserted i join TBL_JOBREQUEST t on t.jobid=i.jobid
    where i.workstatus='Completed' 
    and not exists (
      select * from deleted d 
      where d.jobid=i.jobid and d.workstatus=i.workstatus
    )

end