sql-server - SQL Server - 来自 DATETIME 的 DATE 转换是不确定的,但仅在用户定义的函数中
问题描述
为什么在 SQL Server 的用户定义函数 (UDF) 的返回表中,这种类型转换会因为计算列的不确定性而被拒绝?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
请注意,这不是转换为字符串表示或从字符串表示转换,所以我不知道为什么它不起作用,因为全球化/区域的东西应该是无关紧要的。
这适用于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 定义会关闭它,但我不明白为什么,因为它看起来只是将函数输出标记为基于输入参数的确定性。而且我必须在我的函数中做其他非确定性的事情 ,所以它不是一个候选的解决方法。
不稳定的字符串操作也可能是一种解决方法,但不是可取的。CONVERT
根据 SQL Server ,ISO-8601 的样式 126仍然是不确定的。似乎唯一的选择是放弃使用持久计算列?
解决方案
正如在这个有点相关的答案开头所提到的,不指定WITH SCHEMABINDING
意味着 SQL Server 会跳过对确定性和数据访问等内容的检查。
由于PERSISTED
在计算机列中要求“计算列表达式”是确定性的,并且 SQL Server 会跳过任何检查它是否实际上是确定性的,因此不允许这样做。即使您有像i AS 1 PERSISTED
.
(这与函数本身的所有内容是否都是确定性的无关。)
综上所述,据我所知,在 TVF 中使用PERSISTED
实际上并没有为函数添加任何内容。
推荐阅读
- swift - NSAttributedString 在 10.13 和 10.14+ 上绘制位置不同
- javascript - 修复悬停元素在居中文本中的位置
- elasticsearch - Is there a way to Elasticsearch diferentiate when a field does not exists vs when a field exists but is null ({})
- php - html表单已连接到mysql,但它没有提交任何数据,也没有创建空行
- python - How can I perform 3D array calculations efficiently?
- python - Tkinter - 如何扩展标签小部件?
- jquery - 用不同的起点动态地换行
- c++ - 为什么对向量中类成员的引用指向不同对象的相同值?
- c++ - 如何按字母顺序显示我的数组映射?
- swift - 从目标视图返回时,SwiftUI NavigationLink 显示为突出显示