如何获得日期 + 时间的确定性计算值

How to get a Deterministic computed value for Date + Time

我有一个 table,它有一个日期时间和一个时间字段,其中日期时间实际上只是日期,时间字段是时间。我需要结合这两个字段来创建一个“created_time”计算字段。我想保留这个计算字段,但是当我尝试组合它们时,我不断收到“非确定性”错误。首先,我不确定我是否理解为什么它是不确定的,但其次,有什么奇特的方法可以解决这个问题并实现这个目标吗?

--------------------------------------------------------
       date (datetime)           |       time (varchar)
--------------------------------------------------------
2021-05-05 00:00:00              | 12:00
2021-05-13 00:00:00              | 18:01

我试过使用以下计算,但均无效。

ALTER TABLE dbo.table ADD created_time AS ([date] + [time]) PERSISTED

ALTER TABLE dbo.table ADD created_time AS (DATEADD(millisecond, DATEDIFF(millisecond, 0, [time]), [date])) PERSISTED

首先,+ 运算符对 datetime 值无效,这看起来很奇怪。所以你需要使用你的第二个版本。

其次,你的time列实际上是varchar,所以转换是隐式非确定性转换。

您可以通过使用带有确定性样式参数的 CONVERT 使其具有确定性,例如本例中的 108:

ALTER TABLE dbo.[table] ADD created_time AS
  (DATEADD(millisecond,
      DATEDIFF(millisecond, 0, CONVERT(time, [time], 108)),
  [date])) PERSISTED;

This is documented here,一些样式参数不是确定性的,因为它可能取决于文化和世纪(年份是两位数)。

我强烈建议您将 time 列转换为 time 数据类型,或者更好的是,将其更改为组合的 datetime 列:

ALTER TABLE dbo.[table]
  ALTER COLUMN [time] time NOT NULL;

-- or
ALTER TABLE dbo.[table] ADD created_time datetime NULL;

UPDATE dbo.[table]
SET created_time = (DATEADD(millisecond,
      DATEDIFF(millisecond, 0, CONVERT(time, [time], 108)),
  [date]));

ALTER TABLE dbo.[table]
  DROP COLUMN [time]
  DROP COLUMN [date];

ALTER TABLE dbo.[table] ALTER created_time datetime NOT NULL;