我可以使 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.

String Functions

的链接

同样,此页面声明

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)?如果内置函数是不确定的,就没有办法让它变成这样。有些都取决于参数类型,有些应该是但不是。