A coluna computada não pode ser mantida porque a coluna é não determinística

9

Sei que não é a primeira vez que esse tipo de pergunta é feito.

Mas por que no cenário a seguir a coluna computada persistente está sendo criada "não determinística". A resposta deve sempre ser a mesma, certo?

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

Mensagem 4936, nível 16, estado 1, linha 42 A coluna computada 'UTCTime' na tabela 'teste' não pode ser mantida porque a coluna é não determinística.

Acho que estou seguindo as regras deterministas aqui .

É possível criar uma coluna computada persistida aqui?

Mazhar
fonte

Respostas:

8

A conversão de uma sequência em uma data sem um número de estilo não é determinística, também não há razão para usar um número de estilo ao converter uma data ou data / hora em data / hora2. Tentar:

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

Embora eu esteja curioso por que você precisa persistir nesta coluna. Se for para que você possa indexá-lo, não precisará persistir uma coluna para indexá-lo ...

Aaron Bertrand
fonte
11

Você precisa usar um estilo determinístico ao converter de uma representação de sequência .

Você não estava usando um estilo determinístico com a conversão de string para date.

Você especificou um estilo desnecessariamente ao converter de data para datetime2.

Há uma mistura confusa de tipos de dados de data / hora na pergunta.

Isso funciona (produzindo uma datetimecoluna):

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

Como Aaron mencionou (estávamos respondendo simultaneamente), você não precisa persistir em uma coluna determinística para indexá-la.

Paul White 9
fonte