Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my CASE expression non-deterministic?

I am trying to create a persisted computed column using CASE expression:

ALTER TABLE dbo.Calendar ADD PreviousDate AS 
case WHEN [Date]>'20100101' THEN  [Date]
    ELSE NULL
    END PERSISTED

MSDN clearly says that CASE is deterministic, here

However, I am getting an error:

Msg 4936, Level 16, State 1, Line 1 Computed column 'PreviousDate' in table 'Calendar' cannot be persisted because the column is non-deterministic.

Of course, i can create a scalar UDF and explicitly declare it as deterministic, but is there a simpler way around this? I am already in the middle of getting the latest service pack. Thanks.

like image 536
A-K Avatar asked Aug 29 '10 21:08

A-K


People also ask

What is a non-deterministic function?

Functions can be either deterministic or nondeterministic. A deterministic function always returns the same results if given the same input values. A nondeterministic function may return different results every time it is called, even when the same input values are provided.

Which functions would be considered deterministic?

Deterministic functions always return the same result any time they're called with a specific set of input values and given the same state of the database.

Is Hashbytes deterministic?

Hashbytes Computed column cannot be persisted because the column is non-deterministic.

What is non-deterministic SQL?

An SQL statement is non-deterministic in a replication set if it does not return the same result when executed on all replication nodes in the set. If an SQL statement contains a non-deterministic expression, by-value replication of the expression is performed.


2 Answers

You need to CONVERT '20100101' with a style.

Source or target type is datetime or smalldatetime, the other source or target type is a character string, and a nondeterministic style is specified.

So, try this:

...WHEN [Date] > CONVERT(datetime, '20100101', 112)....

Date parsing from string can be unreliable as I've answered before (mostly in comments)

Edit:

I wouldn't say it's a bug, but SQL Server asking for 100% clarification. yyyymmdd is not ISO and SQL Server parsing yyyy-mm-dd is unreliable (see my answer link)

like image 171
gbn Avatar answered Oct 14 '22 17:10

gbn


Apparently it is very picky about data types. Try doing this:

ALTER TABLE dbo.Calendar ADD PreviousDate AS 
case WHEN [Date ]> Convert(DateTime, '20100101', 101) THEN  [Date]
    ELSE Convert(DateTime, NULL, 101)
    END PERSISTED
like image 37
ChaosPandion Avatar answered Oct 14 '22 15:10

ChaosPandion