我可以使SQL Server FORMAT确定吗?

Mat*_*hew 3 sql-server user-defined-functions sql-server-2014

我想制作一个返回整数形式的UDF,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
Run Code Online (Sandbox Code Playgroud)

但我认为使用它更清洁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
Run Code Online (Sandbox Code Playgroud)

但这个功能是不确定的.有没有办法FORMAT确定性?或者有更好的方法来做到这一点,使UDF确定性?

Lie*_*sel 6

有趣的问题,所以我做了一些挖掘,并没有得出任何结论:)

确定性和非确定性函数开始

没有明确列出FORMAT但是说明:

所有聚合和字符串内置函数都是确定性的.

字符串函数的链接

同样,这个页面说明了

所有内置字符串函数都是确定性的.这意味着只要使用一组特定的输入值调用它们,它们就会返回相同的值.

但是,页面FORMAT上的主题是静默的.

FORMAT使用CLR 并不排除它确定性,但doco对于实际的实现是静默的FORMAT.

最后,怀疑这是doco(或代码)中的一个错误,快速搜索连接没有显示任何内容.

测试用例怎么样?(欢迎评论此代码的有效性......)

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)
Run Code Online (Sandbox Code Playgroud)

Nup,这是不确定的.

所以,一个有趣的练习,但没有定论.

那么我们学到了什么(根据BOL)?如果内置函数是不确定的,那么就无法做到这一点.有些都取决于参数类型,有些应该是但不是.


FLI*_*KER 5

我想知道你为什么使用函数。您可以使用一个简单的公式:

CONVERT(varchar(6), getdate(), 112) 
Run Code Online (Sandbox Code Playgroud)