【问题标题】:Computed column 'AGE' in table 'TABLE1' cannot be persisted because the column is non-deterministic表 'TABLE1' 中的计算列 'AGE' 无法持久化,因为该列是不确定的
【发布时间】:2018-04-19 11:49:05
【问题描述】:

如何解决这个错误?

我正在尝试添加一个带有检查约束的列,即使我保留了该列,我也会收到此错误。

ALTER TABLE TABLE1
ADD AGE AS DATEDIFF(YEAR,DateOFBirth,GETDATE()) PERSISTED
CONSTRAINT CHCK_TABLE1_AGE
CHECK (AGE>0 AND AGE<105)  

错误:

表“TABLE1”中的计算列“AGE”无法持久化,因为 该列是不确定的。

【问题讨论】:

  • 你不能有一个约束,因为 GetDate() 是不确定的。这意味着每次执行时都会得到不同的值。 Deterministic and Nondeterministic Functions
  • 正如错误消息告诉你的那样,你不能坚持它,因为它是不确定的。添加PERSISTED 不会以某种方式修复该值并使其具有确定性。 (如果是这样,Age 将是错误的,因为它会保留一次并且永远不会更新。)删除PERSISTED,它应该是一个合法的计算列。 CHECK 仍然是不可能的,因为 SQL Server 不能突然根据移动时钟声明一行非法! (除此之外——目前,世界上最长寿的人已经 117 岁;这项检查似乎是不必要的限制。)
  • 另一方面,DATEDIFF(YEAR,DateOFBirth,GETDATE() 不会返回此人的年龄。例如。 DATEDIFF(YEAR, '20000901', GETDATE()) 返回 18,但是,在该日期出生的人还不到 18 岁。
  • 如果您的目标是永远不允许添加当前年龄超过 105 岁的人,以捕捉明显的虚假日期,请使用 INSERT 触发器。如果您的目标是确保表从不包含超过 105 岁的人,那么您将需要计划的工作或其他定期机制来检测“太老”的人——尽管我无法想象这是一个真正的商业目标。
  • 年龄

标签: sql sql-server alter-table


【解决方案1】:

是的,该列不是确定性的,所以它不能被索引。

AGE 列值每天都会变化(甚至是小时或秒),因此不能在其上创建索引。

我想到的解决方案是不使用 AS 自动计算此列,而是通过触发器或外部进程每天(晚上)重新计算它。

这样,您每天都会获得正确的年龄值,并且您还将获得快速搜索索引

【讨论】:

  • 感谢您的帮助:)
猜你喜欢
  • 2019-12-21
  • 1970-01-01
  • 2012-12-16
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多