SQL Server - преобразование DATE из DATETIME является недетерминированным, но только в пользовательской функции
Почему это преобразование типов отклонено как недетерминированное для 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
Обратите внимание, что это не преобразование в строковое представление или из него, поэтому я не знаю, почему оно не работает, потому что глобализация / регион не должны иметь значения.
Это работает вне 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
Кажется, что добавление WITH SCHEMABINDING
к определению UDF это закрывает, но я не понимаю почему, потому что это выглядит так, что только помечает выходные данные функции как детерминированные на основе входных параметров. И я должен делать другие недетерминированные вещи в своей функции, так что это не обходной путь кандидата.
Wonky строки манипуляции также может быть обходной путь, но не является предпочтительным. Стиль 126 для ISO-8601 на CONVERT
по-прежнему недетерминирован в соответствии с SQL Server. Кажется, единственный вариант - отказаться от использования постоянных вычисляемых столбцов?
1 ответ
Как уже упоминалось в начале этого несколько связанного ответа, не указав WITH SCHEMABINDING
означает, что SQL Server пропускает проверки на такие вещи, как детерминизм и доступ к данным.
поскольку PERSISTED
в столбце компьютера требуется, чтобы "вычисляемое выражение столбца" было детерминированным, а SQL Server пропускает любые проверки того, является ли оно на самом деле детерминированным или нет, оно не будет разрешено. Та же самая ошибка произойдет, даже если у вас будет что-то столь же простое, как i AS 1 PERSISTED
,
(Это не связано с тем, является ли все в самой функции детерминированным.)
Все что сказано, используя PERSISTED
в TVF фактически ничего не добавляет к функции, насколько я знаю.