SQL Server中计算列的最佳实践

时间:2013-04-05 14:43:31

标签: sql-server sql-server-2012 calculated-columns

我正在使用用户表,并希望设置“试用期结束日期”。基本上,每个新用户从他们作为试用期的一部分加入时有2个完整月份。我看到我可以在我的用户表的列中放置一个公式,但我想知道我是否应该有一个更新此脚本的脚本,或者这是否是使用计算列的可接受时间。我访问此表以获取各种内容,并偶尔会根据性能里程碑成就更新用户行。申请日期永远不会更改/更新。

我的问题是:在这种情况下使用计算列是一个好习惯还是每次更新该行时都会重新计算(即使我不打算更新应用程序日期)?我不希望在将来更新行时产生更多的开销。

公式I在试用结束日期的列定义中使用:

(dateadd(day,(-1),dateadd(month,(3),dateadd(day,(1)-datepart(day,[APP_DT]),[APP_DT]))))

3 个答案:

答案 0 :(得分:15)

看到这个日期很可能在设置后永远不会改变,它可能不是计算列的好选择。

毕竟:一旦你在该表中插入一行,你就可以很容易地计算出“试用期结束”日期然后(例如在触发器中),并且一旦设置,该日期就不会改变。

因此,虽然你绝对可以这样做,但我可能更喜欢使用AFTER INSERT触发器(或INSERT操作的存储过程)来计算一次,然后存储日期。

另外,就像单挑一样:每次访问它时都会计算出只有公式的计算列 - 只需要注意这一点。也就是说,除非你指定PERSISTED关键字,在这种情况下,结果存储在行中的其他数据旁边,这将更适合这里 - 再次,因为该值一旦计算,不一定会再次改变。

答案 1 :(得分:11)

如果您希望稍后延长某人的试用期而不必更改其申请日期,那么计算列就不是可行的方法。为什么不对两列使用DEFAULT约束?

USE tempdb;
GO

CREATE TABLE dbo.foo
(
  MemberID INT IDENTITY(1,1),
  JoinDate DATE NOT NULL DEFAULT SYSDATETIME(),
  ProbationEndDate NOT NULL DEFAULT 
    DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH,0,SYSDATETIME())+3, 0))
);

INSERT dbo.foo DEFAULT VALUES;

SELECT MemberID, JoinDate, ProbationEndDate FROM dbo.foo;

结果:

MemberID    JoinDate      ProbationEndDate
--------    ----------    ----------------
1           2013-04-05    2013-06-30

(注意我用了一个稍微不那么激动的方法来结束这个月的两个月。)

答案 2 :(得分:0)

插入数据时没有开销;只有在读取列时才会为此列计算值。所以我说你的方法是正确的。