La colonna calcolata non può essere mantenuta perché la colonna non è deterministica


9

So che non è la prima volta che questo tipo di domanda è stata posta.

Ma perché nel seguente scenario la colonna calcolata persistente viene creata "non deterministica". La risposta dovrebbe essere sempre la stessa, giusto?

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

Messaggio 4936, livello 16, stato 1, riga 42 La colonna calcolata "UTCTime" nella tabella "test" non può essere mantenuta poiché la colonna non è deterministica.

Penso di seguire le regole deterministiche qui .

È possibile creare una colonna calcolata persistente qui?

Risposte:


8

La conversione di una stringa in una data senza un numero di stile non è deterministica, inoltre non vi è motivo di utilizzare un numero di stile quando si converte una data o un datetime in datetime2. Provare:

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

Anche se sono curioso di sapere perché è necessario persistere in questa colonna. Se è così puoi indicizzarlo, non è necessario persistere una colonna per indicizzarlo ...


11

È necessario utilizzare uno stile deterministico durante la conversione da una rappresentazione di stringa .

Non stavi usando uno stile deterministico con la conversione da stringa a date.

Stavi specificando inutilmente uno stile durante la conversione da data a datetime2.

C'è una confusa combinazione di tipi di dati data / ora nella domanda.

Funziona (producendo una datetimecolonna):

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

Come ha detto Aaron (stavamo rispondendo contemporaneamente), non è necessario persistere una colonna deterministica per indicizzarla.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.