我有一个包含“购买日期”和“保修期限”列的计算机表。我希望每台计算机(行)将“购买日期”中的日期值添加4年,并将结果放入“保修期限”列中。我还希望在创建新计算机时自动发生此情况,并尽可能输入其购买日期。Microsoft SQL 2012基于列值的日期差异
感谢
我有一个包含“购买日期”和“保修期限”列的计算机表。我希望每台计算机(行)将“购买日期”中的日期值添加4年,并将结果放入“保修期限”列中。我还希望在创建新计算机时自动发生此情况,并尽可能输入其购买日期。Microsoft SQL 2012基于列值的日期差异
感谢
删除列,并使其计算:
ALTER TABLE dbo.TableName DROP COLUMN WarrantyExpires;
ALTER TABLE dbo.TableName ADD WarrantyExpires
AS CONVERT(DATE, DATEADD(YEAR, 4, DatePurchased));
或者更好的,甚至不存储此。由于每行都是一样的(假设您没有4年的保证),只需在运行时执行计算即可。
如果每行都不一样,或者客户可以(现在或以后)延长保修期,那么计算列是不可行的。相反:
ALTER TABLE dbo.TableName ADD WarrantyExpires DATE;
然后一个INSTEAD OF
触发也许它依赖于由插入(你会用它来重写),四年自购买日起提供的值(如果提供的到期日没有价值填充)。所以:
CREATE TRIGGER dbo.FixWarrantyDate
ON dbo.TableName
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.TableName(OrderID, /* other cols, */ DatePurchased, WarrantyExpires)
SELECT OrderID, /* other cols, */ COALESCE(DatePurchased,GETDATE()),
COALESCE(WarrantyExpires,DATEADD(YEAR,4,COALESCE(DatePurchased,GETDATE())))
FROM inserted;
END
GO
所以,现在你的基部插入看起来是这样的默认情况下:
INSERT dbo.TableName(OrderID, DatePurchased, WarrantyExpires)
SELECT 1, GETDATE(), NULL;
-- or
INSERT dbo.TableName(OrderID, DatePurchased)
SELECT 2, GETDATE();
-- or even:
INSERT dbo.TableName(OrderID) SELECT 3;
如果有人购买了延长保修期,你可以重写(或更高版本手动更新):在表
INSERT dbo.TableName(OrderID, DatePurchased, WarrantyExpires)
SELECT 4, GETDATE(), DATEADD(YEAR, 5, GETDATE());
所得数据这四个插入件后:
OrderID DatePurchased WarrantyExpires
------- ------------- ---------------
1 2013-10-25 2017-10-25
2 2013-10-25 2017-10-25
3 2013-10-25 2017-10-25
4 2013-10-25 2018-10-25
现在我觉得我也应该解释为什么我更喜欢INSTEAD OF
触发器。虽然他们确实要求你重新写的INSERT语句,这将触发后不这样做,好处,他们补充:
你处理你的业务逻辑后,也仍然可以执行插入(和更新一个后触发器通常处理)在一个单一的陈述。这对日志更友好。
如果触发器中的业务逻辑可能会回滚事务,那么在触发器INSTEAD OF
中这样做会好得多。影响日志,可能导致页面拆分,然后删除行,影响日志,添加需要稍后清理的幻影行,而不是写入行,影响日志,可能导致页面拆分,而不是执行插入。
或有一个计算列:) – Schalk
@Schalk是不是我的答案建议? –