I want to make a UDF which returns an integer form of YYYYMM
so that I can easily partition some things on month. I am trying to assign this function to the value of a PERSISTED
computed column.
I currently have the following, which works fine:
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
But I think it's cleaner to use FORMAT
instead. I tried this:
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
But this function is nondeterministic.
Is there a way to make FORMAT
deterministic? Or is there a better way to do this, making the UDF deterministic?
Interesting question so I did some digging and came up with nothing conclusive :)
Starting with Deterministic and Nondeterministic Functions
which doesn't explicitly list FORMAT
but states:
All of the aggregate and string built-in functions are deterministic.
and links to String Functions
Again, this page states
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.
However, the page on FORMAT
is silent on the subject.
FORMAT
uses the CLR which doesn't preclude it from being deterministic but the doco is silent as to the actual implementation of FORMAT
.
Finally, suspecting this is a bug in the doco (or the code) a quick search of connect reveals nothing.
How about a test case? (Comments welcome on the validity of this code…)
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, that's nondeterministic.
So, an interesting exercise but nothing conclusive.
So what did we learn (according to BOL)? If a built-in function is nondeterministic, there's no way of making it so. Some are both depending on the parameter types, and some are supposed to be but aren't.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With