Die berechnete Spalte kann nicht beibehalten werden, da die Spalte nicht deterministisch ist

9

Ich weiß, dass dies nicht das erste Mal ist, dass diese Art von Frage gestellt wurde.

Aber warum wird im folgenden Szenario die persistierte berechnete Spalte "nicht deterministisch" erstellt? Die Antwort sollte immer dieselbe sein, oder?

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

Meldung 4936, Ebene 16, Status 1, Zeile 42 Die berechnete Spalte 'UTCTime' in der Tabelle 'test' kann nicht beibehalten werden, da die Spalte nicht deterministisch ist.

Ich glaube, ich folge hier den deterministischen Regeln .

Ist es möglich, hier eine persistierte berechnete Spalte zu erstellen?

Mazhar
quelle

Antworten:

8

Das Konvertieren einer Zeichenfolge in ein Datum ohne Stilnummer ist nicht deterministisch. Es gibt auch keinen Grund, eine Stilnummer beim Konvertieren eines Datums oder einer Datums- / Uhrzeitangabe in eine Datums- / Uhrzeitangabe2 zu verwenden. Versuchen:

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

Obwohl ich neugierig bin, warum Sie diese Spalte beibehalten müssen. Wenn es so ist, dass Sie es indizieren können, müssen Sie keine Spalte beibehalten, um es zu indizieren ...

Aaron Bertrand
quelle
11

Sie müssen beim Konvertieren aus einer Zeichenfolgendarstellung einen deterministischen Stil verwenden .

Sie haben bei der Konvertierung von Zeichenfolge zu keinen deterministischen Stil verwendet date.

Sie haben beim Konvertieren von Datum nach unnötig einen Stil angegeben datetime2.

Die Frage enthält eine verwirrende Mischung von Datums- / Zeitdatentypen.

Dies funktioniert (Erstellen einer datetimeSpalte):

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

Wie Aaron erwähnte (wir antworteten gleichzeitig), müssen Sie keine deterministische Spalte beibehalten, um sie zu indizieren.

Paul White 9
quelle