SQL Server - преобразование DATE из DATETIME является недетерминированным, но только в пользовательской функции - PullRequest
0 голосов
/ 14 декабря 2018

Почему это преобразование типа отклонено как недетерминированное для вычисляемого столбца PERSISTED в таблицах возврата пользовательских функций (UDF) в SQL Server?

CREATE FUNCTION MyTimeIntervalFunction(@Param1 INT)
RETURNS @MyTimeInterval TABLE
(
     StartUtc   DATETIME    NOT NULL PRIMARY KEY
    ,EndUtc     DATETIME    NOT NULL
    ,DateUtc    AS CONVERT(DATE, StartUtc) PERSISTED
)
AS BEGIN
    --do stuff
    RETURN
END

enter image description here

Обратите внимание, что это не преобразование в или из строкового представления, поэтому я не будузнаю, почему это не работает, потому что глобализация / регион должны быть неактуальными.

Это работает вне UDF (включая хранимые процедуры):

DECLARE @MyTimeInterval TABLE
(
     StartUtc   DATETIME    NOT NULL PRIMARY KEY
    ,EndUtc     DATETIME    NOT NULL
    ,DateUtc    AS CONVERT(DATE, StartUtc) PERSISTED
)
INSERT INTO @MyTimeInterval(StartUtc, EndUtc)
VALUES ('2018-01-01', '2018-01-02')
SELECT * FROM @MyTimeInterval

enter image description here

Кажется, что добавление WITH SCHEMABINDING к определению UDF закрывает его, но я не понимаю почему, потому что, похоже, это только отмечаетфункция выводит как детерминированная на основе входных параметров.И я должен сделать другие недетерминированные вещи в моей функции, так что это не обходной путь кандидата.

Wonky манипулирование строками также может бытьОбходной путь, но не является предпочтительным. Стиль 126 для ISO-8601 на CONVERT по-прежнему недетерминирован в соответствии с SQL Server.Кажется, единственный вариант - отказаться от использования сохраненных вычисляемых столбцов?

1 Ответ

0 голосов
/ 18 декабря 2018

Как уже упоминалось в начале , этот несколько связанный ответ без указания WITH SCHEMABINDING означает, что SQL Server пропускает проверки на такие вещи, как детерминизм и доступ к данным.

Поскольку PERSISTED в столбце компьютера требует, чтобы «вычисляемое выражение столбца» было детерминированным, а SQL Server пропускает любые проверки того, является ли он на самом деле детерминированным, оно не будет разрешено.Та же самая ошибка произошла бы, даже если бы у вас было что-то столь же простое, как i AS 1 PERSISTED.

(Это не связано с тем, является ли все в самой функции детерминированным.)

Насколько я знаю, использование PERSISTED в TVF фактически ничего не добавляет к функции.

...