HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlModerate

Likelihood for Discrepancy in GETDATE() Values Within UPDATE Statement

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
updategetdatestatementdiscrepancywithinlikelihoodforvalues

Problem

As the title alludes to I am wondering if it is possible or if you have experienced an issue with differing GETDATE() results within the same UPDATE statement.

I have a stored procedure which updates a record that contains two DateTime columns, there is also a CASE statement therein, generally the update is as follows:

UPDATE A
        SET Status = dbo.func('P')
           ,Time1 = GETDATE()
           ,Time2 = ISNULL(A.Time2, GETDATE())
           ,ModifiedOn = GETDATE()
        FROM dbo.Table A
        WHERE A.ID = @ID
        AND A.RowID = @RowID;


I am seeing the Time2 value be slightly later, but always in an increment of 3 or 4. This seems to be due SQL server rounding the datetime to the nearest 0.000, 0.003, 0.007 by design Stack Post Here.

I am thinking this discrepancy is being caused by a slight delay between the two GETDATE() calls and that the delay generally accounts for one 'tick' since I only ever see the difference between Time2 - Time1 = {-.003, -.004}.

Is it possible for the aforementioned query to return two distinct GETDATE() results?

Solution

GETDATE is one of the intrinsics considered to be a runtime constant. It is evaluated once at statement startup and then returns the same cached value for every row.

Each instance of a runtime constant is cached separately. Each will therefore return the same value every time it is evaluated, but the initially cached values may vary by a small amount.

You have three such instances.

To be clear: In your example, the value stored in Time1 will be the same in every row. The value stored in Time2 will be the same in every row. The value stored in ModifiedOn will be the same in every row. The values in Time1, Time2, and ModifiedOn may differ.

If you want the values to always be the same, the safest way is to assign the value of GETDATE to a variable and use the variable in the target statement instead:

DECLARE 
    @Now datetime = GETDATE();

UPDATE A
SET [Status] = dbo.func('P'),
    Time1 = @Now,
    Time2 = ISNULL(A.Time2, @Now),
    ModifiedOn = @Now
FROM dbo.[Table] AS A
WHERE
    A.ID = @ID
    AND A.RowID = @RowID;

Code Snippets

DECLARE 
    @Now datetime = GETDATE();

UPDATE A
SET [Status] = dbo.func('P'),
    Time1 = @Now,
    Time2 = ISNULL(A.Time2, @Now),
    ModifiedOn = @Now
FROM dbo.[Table] AS A
WHERE
    A.ID = @ID
    AND A.RowID = @RowID;

Context

StackExchange Database Administrators Q#319500, answer score: 11

Revisions (0)

No revisions yet.