Вычисляемый столбец не может быть сохранен, потому что столбец недетерминирован

9

Я знаю, что это не первый раз, когда задают такой вопрос.

Но почему в следующем сценарии постоянный вычисляемый столбец создается «недетерминированным». Ответ всегда должен быть одинаковым, верно?

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

Сообщение 4936, уровень 16, состояние 1, строка 42 Вычисляемый столбец «UTCTime» в таблице «test» не может быть сохранен, поскольку столбец недетерминирован.

Я думаю, что я следую определенным правилам здесь .

Можно ли здесь создать постоянный вычисляемый столбец?

Mazhar
источник

Ответы:

8

Преобразование строки в дату без номера стиля не является детерминированным, также нет причин использовать номер стиля при преобразовании даты или даты-времени в datetime2. Пытаться:

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

Хотя мне любопытно, почему вы должны сохранять эту колонку. Если это так, вы можете проиндексировать его, вам не нужно сохранять столбец, чтобы проиндексировать его ...

Аарон Бертран
источник
11

Вам необходимо использовать детерминированный стиль при преобразовании из строкового представления.

Вы не использовали детерминированный стиль с преобразованием из строки в date.

Вы излишне указали стиль при конвертации из даты в datetime2.

В вопросе есть смешанная комбинация типов данных дата / время.

Это работает (производит datetimeколонку):

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

Как отметил Аарон (мы отвечали одновременно), вам не нужно сохранять детерминированный столбец для его индексации.

Пол Уайт 9
источник