Защо моята SQL функция е недетерминирана, когато не трябва да бъде?

Според MS docs DATEADD е детерминистична функция, следователно моята функция по-долу също трябва да е детерминистична:

CREATE FUNCTION [dbo].[Epoch2Date] (@i INT)
RETURNS DATETIME WITH SCHEMABINDING
BEGIN
    RETURN DATEADD(SECOND,@i,'1970-01-01 00:00:00')
END

Но когато го проверя с SELECT OBJECTPROPERTY(OBJECT_ID('[dbo].[Epoch2Date]'), 'IsDeterministic'), той връща 0 (недетерминиран).

  1. Защо е недетерминиран?
  2. Как мога да направя функцията си детерминистична?

Има подобен въпрос, но използва недетерминирана функция CAST, което не е случаят тук.


person endo64    schedule 21.02.2021    source източник


Отговори (1)


DATEADD е. Неявното преобразуване на varchar в datetime обаче не е. Това е особено по-лошо, когато форматът, който използвате, е двусмислен за datetime (макар че поне стойността ще бъде същата).

Трябва изрично да конвертирате стойността със стил:

DATEADD(SECOND,@i,CONVERT(datetime,'19700101',112))
person Larnu    schedule 21.02.2021
comment
Благодаря! Това реши проблема. Би било хубаво да отбележите това на страницата с документи на MS. - person endo64; 22.02.2021
comment
Това е, @endo64 , в документа, който цитирах във въпроса, който сте свързали. Неявното предаване/преобразуване все още е предаване/преобразуване. При опита ви имате стойност на символен низ ('1970-01-01 00:00:00'), вие имплицитно преобразувате/преобразувате без стил в datetime; и това е изрично дефинирано като недетерминистично. - person Larnu; 22.02.2021
comment
Разбирам, имах предвид, че би било хубаво да се отбележи, че DATEADD прави имплицитно преобразуване, което води до недетерминиране. - person endo64; 22.02.2021
comment
Ако смятате, че не е точно, @endo64, тогава направете заявка за изтегляне на документа; въпреки че аз лично смятам, че го покрива (имплицитно :)). - person Larnu; 22.02.2021