计算列无法保留,因为该列是不确定的


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行表格'test'中的计算列'UTCTime'无法保留,因为该列是不确定的。

我认为我在这里遵循确定性规则

是否可以在此处创建一个持久化的计算列?

Answers:


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;

正如Aaron所提到的(我们正在同时回答),您不需要持久性使用确定性列来为其编制索引。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.