Why is casting a DATE field to VARCHAR datatype non-deterministic and is there a way to make it deterministic?
Domanda
I'm trying to create an indexed view where the index is on a field in the view which is a hash of a bunch of the columns of the underlying table in the view.
Here's an example:
CREATE VIEW CoolHashedView WITH SCHEMABINDING AS
SELECT
KeyId,
CONVERT
(
VARCHAR(34),
HASHBYTES('MD5', TextColumn1 + '||' + TextColumn2 + '||' + CAST(DateColumn1 AS VARCHAR(50)),
2
) AS HashedData
FROM dbo.BoringTable;
CREATE UNIQUE CLUSTERED INDEX IX_CoolHashedView_KeyId_HashedData ON CoolHashedView (KeyId, HashedData);
When I try to create the above index, it fails and the following error is thrown:
Msg 2729, Level 16, State 1, Line 26 Column 'HashedData' in view 'CoolHashedView' cannot be used in an index or statistics or as a partition key because it is non-deterministic.
When I remove the date field from the HASHBYTEs function, the clustered index then successfully creates.
My guess is it has something to do with the different ways to format a date or different timezones?...am I getting warmer?
Soluzione
CAST is not deterministic because date format may change based on the server settings (i.e. under compatibility before 110 default date format is 0 => "Dec 12 2019 2:11PM" and output dependeds on language).
To make it deterministic use CONVERT and
the style parameter must be a constant. Additionally, styles less than or equal to 100 are nondeterministic, except for styles 20 and 21. Styles greater than 100 are deterministic, except for styles 106, 107, 109 and 113. (from documentation below)
More documentation at: Deterministic and Nondeterministic Functions