我可以使SQL Server FORMAT确定吗?

时间:2016-06-03 18:46:26

标签: sql-server sql-server-2014 user-defined-functions

我想创建一个返回整数形式YYYYMM的UDF,以便我可以在一个月内轻松地对某些内容进行分区。我试图将此函数分配给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确定性吗?

3 个答案:

答案 0 :(得分:6)

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

Deterministic and Nondeterministic Functions

开始

并未明确列出FORMAT,但声明:

  

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

以及指向String Functions

的链接

同样,此页面说明了

  

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

但是,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)

Nup,那是不确定的。

所以,这是一项有趣的练习,但没有定论。

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

答案 1 :(得分:3)

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

CONVERT(varchar(6), getdate(), 112) 

答案 2 :(得分:1)

微软并不清楚格式功能是否具有决定性。我在其文档中找不到关于该主题的任何信息。作为一个CLR功能,我猜这是不可能的。

一个更简单的解决方案,可以按照你想要的方式获得一个整数:

YEAR(@pDate) * 100 + MONTH(@pDate)