我正在尝试创建一个触发器,当记录达到“ 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'值。
答案 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