SQL 服务器 - DATETIME 的 DATE 转换是不确定的,但仅在用户定义的函数中

SQL Server - DATE conversion from DATETIME is non-deterministic but only in user-defined function

为什么这种类型转换在 SQL 服务器的 return 用户定义函数 (UDF) 表中被拒绝为 non-deterministic for a PERSISTED 计算列?

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

请注意,这不是将 or from 字符串表示形式转换,所以我不知道为什么它不起作用,因为 globalization/region 东西应该是无关紧要的。

这在 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 to the UDF definition shuts it up, but I don't understand why, because it looks like that only marks the function output as deterministic based on input parameters. And I have to do other non-deterministic stuff,所以它不是一个候选解决方法。

Wonky string manipulation could also be a workaround, but is not preferable. Style 126 for ISO-8601 on CONVERT 根据 SQL 服务器仍然是不确定的。似乎唯一的选择是放弃使用持久化计算列?

this somewhat related answer开头所述,不指定WITH SCHEMABINDING意味着SQL服务器跳过对确定性和数据访问等事项的检查。

由于计算机列中的 PERSISTED 要求 "computed column expression" 是确定性的,而 SQL 服务器会跳过任何关于它是否确实是确定性的检查,因此不允许这样做.即使你有像 i AS 1 PERSISTED.

这样简单的东西,也会发生同样的错误

(这与函数本身的一切是否是确定性无关。)

综上所述,据我所知,在 TVF 中使用 PERSISTED 实际上并没有给函数添加任何内容。