我可以使 SQL 服务器格式具有确定性吗?
Can I make SQL Server FORMAT deterministic?
我想制作一个 UDF,其中 returns 是 YYYYMM
的整数形式,这样我就可以轻松地在月内划分一些东西。我正在尝试将此函数分配给 PERSISTED
计算列的值。
我目前有以下,效果很好:
CREATE FUNCTION dbo.GetYearMonth(@pDate DATETIME2)
RETURNS INT
WITH SCHEMABINDING
AS
BEGIN
DECLARE @fYear VARCHAR(4) = RIGHT('0000' + CAST(YEAR(@pDate) AS VARCHAR),4)
DECLARE @fMonth VARCHAR(2) = RIGHT('00' + CAST(MONTH(@pDate) AS VARCHAR),2)
RETURN CAST(@fYear + @fMonth AS INT)
END
但我认为使用 FORMAT
更简洁。我试过这个:
CREATE FUNCTION dbo.GetYearMonth(@pDate DATETIME2)
RETURNS INT
WITH SCHEMABINDING
AS
BEGIN
DECLARE @fYear VARCHAR(4) = FORMAT(@pDate,'yyyy', 'en-us')
DECLARE @fMonth VARCHAR(2) = FORMAT(@pDate,'MM', 'en-us')
RETURN CAST(@fYear + @fMonth AS INT)
END
但是这个函数是不确定的。
有没有办法让 FORMAT
具有确定性?或者是否有更好的方法来执行此操作,使 UDF 具有确定性?
我想知道你为什么要使用函数。
您可以使用一个简单的公式:
CONVERT(varchar(6), getdate(), 112)
Microsoft 不是很清楚格式化函数是确定性的。我在其文档中找不到有关该主题的任何信息。作为 CLR 函数,我猜 awnser 是不可能的。
一个更简单的解决方案,可以按照您想要的方式格式化整数:
YEAR(@pDate) * 100 + MONTH(@pDate)
有趣的问题,所以我进行了一些挖掘,但没有得出任何结论:)
从 Deterministic and Nondeterministic Functions
开始
它没有明确列出 FORMAT
但指出:
All of the aggregate and string built-in functions are deterministic.
的链接
同样,此页面声明
All built-in string functions are deterministic. This means they return the same value any time they are called with a specific set of input values.
然而,the page on FORMAT
对这个问题保持沉默。
FORMAT
使用 doesn't preclude it from being deterministic 的 CLR,但 doco 对 FORMAT
.
的实际实现保持沉默
最后,怀疑这是 doco(或代码)中的错误 quick search of connect 什么也没发现。
测试用例怎么样? (欢迎评论此代码的有效性......)
CREATE FUNCTION WhatAmI(@Number INTEGER)
RETURNS NVARCHAR
WITH SCHEMABINDING
AS
BEGIN
RETURN FORMAT(@Number, 'd')
END
GO
SELECT OBJECTPROPERTY(OBJECT_ID('WhatAmI'),'IsDeterministic')
-----------
0
(1 row(s) affected)
不对,这是不确定的。
所以,一个有趣的练习,但没有定论。
那么我们学到了什么(根据 BOL)?如果内置函数是不确定的,就没有办法让它变成这样。有些都取决于参数类型,有些应该是但不是。
我想制作一个 UDF,其中 returns 是 YYYYMM
的整数形式,这样我就可以轻松地在月内划分一些东西。我正在尝试将此函数分配给 PERSISTED
计算列的值。
我目前有以下,效果很好:
CREATE FUNCTION dbo.GetYearMonth(@pDate DATETIME2)
RETURNS INT
WITH SCHEMABINDING
AS
BEGIN
DECLARE @fYear VARCHAR(4) = RIGHT('0000' + CAST(YEAR(@pDate) AS VARCHAR),4)
DECLARE @fMonth VARCHAR(2) = RIGHT('00' + CAST(MONTH(@pDate) AS VARCHAR),2)
RETURN CAST(@fYear + @fMonth AS INT)
END
但我认为使用 FORMAT
更简洁。我试过这个:
CREATE FUNCTION dbo.GetYearMonth(@pDate DATETIME2)
RETURNS INT
WITH SCHEMABINDING
AS
BEGIN
DECLARE @fYear VARCHAR(4) = FORMAT(@pDate,'yyyy', 'en-us')
DECLARE @fMonth VARCHAR(2) = FORMAT(@pDate,'MM', 'en-us')
RETURN CAST(@fYear + @fMonth AS INT)
END
但是这个函数是不确定的。
有没有办法让 FORMAT
具有确定性?或者是否有更好的方法来执行此操作,使 UDF 具有确定性?
我想知道你为什么要使用函数。 您可以使用一个简单的公式:
CONVERT(varchar(6), getdate(), 112)
Microsoft 不是很清楚格式化函数是确定性的。我在其文档中找不到有关该主题的任何信息。作为 CLR 函数,我猜 awnser 是不可能的。
一个更简单的解决方案,可以按照您想要的方式格式化整数:
YEAR(@pDate) * 100 + MONTH(@pDate)
有趣的问题,所以我进行了一些挖掘,但没有得出任何结论:)
从 Deterministic and Nondeterministic Functions
开始它没有明确列出 FORMAT
但指出:
的链接All of the aggregate and string built-in functions are deterministic.
同样,此页面声明
All built-in string functions are deterministic. This means they return the same value any time they are called with a specific set of input values.
然而,the page on FORMAT
对这个问题保持沉默。
FORMAT
使用 doesn't preclude it from being deterministic 的 CLR,但 doco 对 FORMAT
.
最后,怀疑这是 doco(或代码)中的错误 quick search of connect 什么也没发现。
测试用例怎么样? (欢迎评论此代码的有效性......)
CREATE FUNCTION WhatAmI(@Number INTEGER)
RETURNS NVARCHAR
WITH SCHEMABINDING
AS
BEGIN
RETURN FORMAT(@Number, 'd')
END
GO
SELECT OBJECTPROPERTY(OBJECT_ID('WhatAmI'),'IsDeterministic')
-----------
0
(1 row(s) affected)
不对,这是不确定的。
所以,一个有趣的练习,但没有定论。
那么我们学到了什么(根据 BOL)?如果内置函数是不确定的,就没有办法让它变成这样。有些都取决于参数类型,有些应该是但不是。