计算列无法持久化,因为该列是不确定的

Maz*_*har 13 sql-server sql-server-2012 computed-column

我知道这不是第一次被问到这类问题。

但是为什么在以下场景中创建的持久计算列是“非确定性的”。答案应该总是一样的,对吧?

CREATE TABLE dbo.test (Id INT, EventTime DATETIME NULL, PosixTime INT NOT NULL)
GO

DECLARE @EventTime DATETIME =  '20181001 12:00:00'
DECLARE @GPSTime INT = DATEDIFF(SECOND, '19700101', @EventTime)
INSERT INTO dbo.Test(Id, EventTime, PosixTime) 
VALUES (1, @EventTime, @GPSTime)
    , (2, NULL, @GPSTime)
GO

SELECT * FROM dbo.test
GO

ALTER TABLE dbo.test ADD UTCTime AS CONVERT(DATETIME2,ISNULL(EventTime, DATEADD(SECOND, PosixTime, CONVERT(DATE,'19700101'))),112) PERSISTED
GO
Run Code Online (Sandbox Code Playgroud)

消息 4936,级别 16,状态 1,第 42 行无法保留表 'test' 中的计算列 'UTCTime',因为该列是不确定的。

我想我在这里遵循了确定性规则

是否可以在此处创建持久化计算列?

Aar*_*and 11

将字符串转换为没有样式编号的日期是不确定的,在将日期或日期时间转换为 datetime2 时也没有理由使用样式编号。尝试:

ALTER TABLE dbo.test 
    ADD UTCTime AS CONVERT(datetime2,ISNULL(EventTime, 
    DATEADD(SECOND, PosixTime, CONVERT(datetime,'1970-01-01',120)))) 
    PERSISTED;
Run Code Online (Sandbox Code Playgroud)

虽然我很好奇你为什么需要坚持这个专栏。如果是这样你可以索引它,你不需要坚持一列来索引它......


Pau*_*ite 11

字符串表示转换时,您需要使用确定性样式。

您没有使用确定性样式将字符串转换为date.

从日期转换为datetime2.

问题中日期/时间数据类型的混合令人困惑。

这有效(产生一datetime列):

ALTER TABLE dbo.test 
ADD UTCTime AS 
    ISNULL
    (
        EventTime,
        DATEADD
        (
            SECOND, 
            PosixTime, 
            CONVERT(datetime, '19700101', 112)
        )
    )
    PERSISTED;
Run Code Online (Sandbox Code Playgroud)

正如 Aaron 所提到的(我们同时回答),您不需要保留确定性列来对其进行索引。