Evaluating GETDATE twice in a statement - will it always evaluate to be the same?
Asked Answered
S

5

6

suppose

isnull(some_column, getdate()) >= getdate()

where logic is if some_column is null this expression should always be true. However will this always be so (since between two evaluations of getdate() some time has passed and they won't be equal) ?

Shapeless answered 20/8, 2012 at 8:53 Comment(0)
E
7

No, is not safe. You are facing so called runtime constants expressions, of which GETDATE() is the bookcase example, which are evaluate once at query startup and the subsequently the cached evaluated value is used. However each occurence is evaluated separately once and the two evaluation can fall on the separate sides of the datetime precision boundary, resulting in two different values.

A simple test reveals how this happens:

declare @cnt int = 0, @i int = 0
while @cnt = 0 
begin
    select @cnt = count(*)
    from master..spt_values 
    where getdate() != getdate();
    set @i += 1;
    if @cnt != 0
        raiserror(N'@cnt = %d this shoudl not happen but it dit after @i = %d', 16, 1, @cnt, @i);
end

In my case this was hit right away:

Msg 50000, Level 16, State 1, Line 9
@cnt = 2515 this shoudl not happen but it dit after @i = 694

I'm not addressing the question how to better do this (you already got plenty of advice) but the underlying question whether your assumption about the run-time execution is right (is not):

GETDATE() twice in a statement will be evaluate twice

Earthquake answered 20/8, 2012 at 8:59 Comment(0)
W
3

Since you are looking for true in the condition, you don't need to use getDate() twice. Just put in a very large date instead...

For example:

isnull(some_column, '2999-01-01') >= getDate()

as in

declare @some_column(datetime)
select case when isnull(@some_column,'2999-01-01') >= getdate() then 1 else 0 end

which returns 1.

Alternatively you can do it properly and check for the null explicitly:

(some_column >= getdate() or some_column is null)
Wrung answered 20/8, 2012 at 8:59 Comment(0)
T
3

In SQL Server 2000 and previous versions, getdate() is a deterministic function evaluated ONCE per SQL sentence. From 2005 and on, getdate is NOT deterministic, it's evaluated each time so you should assign the value to a variable.

Toledo answered 20/8, 2012 at 9:11 Comment(0)
E
2

Since you are invoking GETDATE() twice, this may fail, though most of the time it will work right.

You can do the following to mitigate:

DECLARE currentDate DATETIME

SELECT currentDate = GETDATE()

isnull(some_column, currentDate) >= currentDate 
Escarpment answered 20/8, 2012 at 8:57 Comment(0)
J
0

Why do you want to use date. I mean there is no reason to ask sql server to evaluate/process for a default true condition. You can instead use

isnull(some_column, 2) >= 1
Jiggered answered 20/8, 2012 at 11:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.