web-dev-qa-db-ja.com

列が非決定的であるため、計算列を永続化できません

このタイプの質問が行われたのはこれが初めてではありません。

しかし、次のシナリオで永続的な計算列が「非決定的」に作成されるのはなぜですか。答えはいつも同じでしょ?

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テーブル 'test'の計算列 'UTCTime'は、列が非決定的であるため保持できません。

私は ここでの決定規則 に従っていると思います。

ここに永続的な計算列を作成することはできますか?

8
Mazhar

文字列をスタイル番号のない日付に変換することは確定的ではありません。また、日付または日時をdatetime2に変換するときにスタイル番号を使用する理由はありません。試してください:

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

なぜこのコラムを永続化する必要があるのか​​知りたいのですが。インデックスを作成できる場合は、インデックスを作成するために列を永続化する必要はありません...

7
Aaron Bertrand

string表現から変換する場合は、確定的なスタイルを使用する必要があります。

文字列からdateへの変換で確定的なスタイルを使用していませんでした。

日付からdatetime2への変換時にスタイルを不必要に指定していました。

質問には、日付と時刻のデータ型が混同されています。

これは機能します(datetime列を生成します):

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

Aaronが述べたように(同時に回答しました)、インデックスを付けるために確定的な列を永続化する必要はありません。

10
Paul White 9