如何使用触发器根据日期更改列值?

时间:2019-01-07 20:47:57

标签: sql sql-server

我正在尝试创建一个触发器,当记录达到“ EndDate”列中的指定结束日期时,该触发器将更改“ RateID”列中的值。

ALTER TRIGGER tr_tblContractExtension_RateChange
ON [dbo].[AgreementExtensionHistory]
AFTER UPDATE, INSERT
AS
   UPDATE AgreementExtensionHistory
   SET RateID = 114
   FROM Inserted i
   WHERE i.EndDate = CURRENT_TIMESTAMP

GO

再次,我希望到达enddate列中的结束日期时,RateID默认为'114'值。

2 个答案:

答案 0 :(得分:0)

非常确定您需要在更新中包括AgreementExtensionHistory,否则它将更新整个表。

类似的事情可能是您追求的。

UPDATE aeh
SET RateID = 114
FROM Inserted i
join AgreementExtensionHistory aeh on aeh.YourKeyColumn = i.YourKeyColumn
--WHERE i.EndDate = CURRENT_TIMESTAMP
WHERE datediff(MILLISECOND, i.EndDate, Current_Timestamp) < 500 --within 1/2 second

是的,问题是您的触发器使用current_timestamp作为连接谓词。您的代码假定触发器中的时间值与插入值相同。情况并非如此,因为插入和触发器是单独的对象。他们每个人都有自己的current_timestamp值,并且永远不会完全相同。

使用简单的表和触发器即可轻松证明这一点。

create table TriggerTest(SomeCol varchar(10), SomeDate datetime not null default CURRENT_TIMESTAMP)

GO

create Trigger trTriggerTest on TriggerTest AFTER insert
AS
    select *
        , CURRENT_TIMESTAMP
    from inserted

GO

insert TriggerTest(SomeCol) select 'test'

-编辑- 大声笑。经过更多测试之后,似乎有时日期值是相同的,而其他时候似乎并不使这种方法更加脆弱。

答案 1 :(得分:0)

尝试以下

ALTER TRIGGER tr_tblContractExtension_RateChange
ON [dbo].[AgreementExtensionHistory]
INSTEAD OF UPDATE, INSERT
AS
   INSERT INTO AgreementExtensionHistory (<Columns Here>)
   SELECT <Columns Here> --instead of RateID  column use CASE expression
          CASE WHEN EndDate = CURRENT_TIMESTAMP THEN 114
               ELSE RateID END
   FROM INSERTED;
GO

我建议至少在EndDate中添加2秒作为

CASE WHEN DATEADD(Second, 2,EndDate) = CURRENT_TIMESTAMP THEN 114
     ELSE RateID END

CASE WHEN DATEDIFF(Second, CURRENT_TIMESTAMP, EndDate) <= 5 --within 5 seconds
     THEN 114
     ELSE RateID END