2012-11-29 48 views
4

我需要在SQL Server数据库中创建一个列age如何创建从另一列计算出的列?

该列的值应根据列DOB的值计算。

其值也应该增加,因为Age增加。

+0

以及新添加的行如何? – paragy

+0

只有当您选择表格的值时,或者当您访问任何人时才会知道年龄是否最新。所以你可以使用触发器/存储程序来做到这一点..不是吗? [类似的线路上的东西](http://stackoverflow.com/questions/12329149/calculating-age-from-birthday-with-oracle-plsql-trigger-and-insert-the-age-in-ta) – bonCodigo

+0

我会只需在表格顶部创建一个视图,最后一列视图定义为'datediff(yy,DOB,getUTCDate())'。 – Vikdor

回答

8

您应该使用计算列来解决此问题。一些与此类似的定义:

ALTER TABLE Customers ADD Age AS datediff(year, DOB ,getdate()) 

BlackWasp从和可用的更多信息,采取原始语句。

编辑:

MSDN解释为计算列:

计算列由能够在同一个表使用其它 列的表达式来计算。该表达式可以是一个或多个运算符的名称,常量,函数以及这些连接的任何组合的非计算列 。表达式不能是子查询。

除非另有规定,否则计算列是虚拟列, 未物理存储在表中。每次在查询中引用它们的值时,都会重新计算它们的值 。数据库引擎在CREATE TABLE和ALTER TABLE语句中使用 PERSISTED关键字 将计算列物理存储在表中。它们的值是 ,当它们的计算中的任何列发生更改时都会更新。通过 将计算列标记为PERSISTED,您可以在确定性但不精确的计算列上创建索引。另外,如果计算列引用CLR函数,则数据库引擎 无法验证函数是否确实是确定性的。在此 的情况下,计算列必须是PERSISTED,以便可以在其上创建索引 。有关更多信息,请参阅在计算的 列上创建索引。

计算列用作CHECK,对外:

计算列可以在选择列表,WHERE子句,ORDER BY 条款,或任何其它位置中的正则表达式可以是 使用的,但有以下例外可以使用KEY或NOT NULL约束必须标记为 PERSISTED。如果计算列值由 确定性表达式定义,并且索引 列允许结果的数据类型,则计算列可用作索引中的键列或作为主键或UNIQUE约束的任何部分。

例如,如果表中有整数列a和b,计算列A + B可以 索引,但在计算列a + DATEPART(DD,GETDATE())不能被索引,因为 值可能会改变>在随后的调用中。

计算列不能是INSERT或UPDATE语句的目标。

数据库引擎根据使用的表达式自动确定 计算列的可空性。大多数 表达式的结果即使仅存在不可空列 ,也被视为可以为空,因为可能的下溢或溢出也会产生 空结果。使用COLUMNPROPERTY函数与AllowsNull属性调查表中任何计算的 列的可空性。通过指定ISNULL(check_expression,常量), (其中常量是一个非空值代替任何空结果),可以为空的表达式可变为 不可空的表达式。

来源:MSDN - Computed Columns

+0

我建议你在这里添加一些信息,而不仅仅是链接。就像什么是计算列一样,它可以被执行,可以被索引,等等。 –

+0

完成。我冒昧地引用了MSDN – SchmitzIT

+0

很好的描述,但它确实没有找到年龄。它发现两个日期之间的整年差异。 DOB ='2012-12-31',getdate()='2013-01-01'= 1年 –

1

这是越来越时代的正确方法:

alter table <yourtable> add age as datediff(year, DOB, getdate())- case when month(DOB)*32 + day(DOB) > month(getdate()) * 32 + day(getdate()) then 1 else 0 end 
4

代码片断

ALTER TABLE 
    TheTable 
ADD 
    DOB AS 
    CASE 
     WHEN 
       MONTH(Birth) > MONTH(ISNULL(Death, SYSDATETIME())) 
      OR (
         MONTH(Birth) = MONTH(ISNULL(Death, SYSDATETIME())) 
        AND DAY(Birth) >= DAY(ISNULL(Death, SYSDATETIME())) 
       ) 
     THEN 
      DATEDIFF(YEAR, Birth, ISNULL(Death, SYSDATETIME())) - 1 
     ELSE 
      DATEDIFF(YEAR, Birth, ISNULL(Death, SYSDATETIME())) 
    END 
1

与自动生成的列创建表,

CREATE TABLE Person2 
(Id int IDENTITY(1,1) NOT NULL, Name nvarchar(50), 
DOB date, Age AS DATEDIFF(YEAR, DOB ,GETDATE()))