Will GETUTCDATE() return the same value if used twice in the same statement?

Solution 1:

Thanks to the links provided by gbn, I believe this answers my question:

In common with rand() It is evaluated once per column but once evaluated remains the same for all rows. ... look at the ComputeScalar operator properties in the actual execution plan you will see that GetDate() is evaluated twice.

I checked, and it appears that this still happens the same way in SQL Server 2008: GetUtcDate() is evaluated twice in the execution plan. It is not going to produce different results per row, but it is possible that it could produce a different result per column if the timing ended up just right.

Edit

I can actually prove this behavior! Try this:

select GETUTCDATE(), RAND(), RAND(), ...[~3000 RAND()s]..., RAND(), GETUTCDATE()
from [TableOfYourChoice]

In my experiment, I ended up with 2011-05-17 20:47:34.247 in the first column and 2011-05-17 20:47:34.250 in the final column, showing a difference of three milliseconds as a result of the evaluation of all the RAND()s between the first and second calls to GETUTCDATE().

Solution 2:

DECLARE @Counter INT = 1

WHILE (1 = (SELECT 1 WHERE GETUTCDATE()  = GETUTCDATE()))
SET @Counter = @Counter+1

SELECT @Counter /*Returns almost immediately with a number in the 000s for me.*/

And just to prove this happens when in the SELECT list also.

DECLARE @T TABLE 
(
rownum INT IDENTITY(1,1) PRIMARY KEY,
d1 datetime,
d2 datetime
)

WHILE (NOT EXISTS(SELECT * FROM @T WHERE d1 <> d2))
    BEGIN
    DELETE FROM @T
    INSERT INTO @T 
    SELECT GETUTCDATE(),GETUTCDATE()
    END

SELECT * FROM @T

BTW: IF for some reason you want to evaluate GETUTCDATE() on a per row basis you can wrap it in a scalar UDF.

CREATE FUNCTION dbo.GETUTCDATE()
RETURNS DATETIME
WITH SCHEMABINDING
AS
BEGIN
RETURN GETUTCDATE()
END
GO

SELECT GETUTCDATE(),dbo.GETUTCDATE()
FROM master..spt_values

Solution 3:

Keeping the GETUTCDATE() in a variable is a better option as it assures that CreationDate and ModifiedDate remains same. However, I called GETUTCDATE() number of time per query and they all returned the same value, so to me it seems that GETUTCDATE() value remains same per query.

Solution 4:

It will be the same value.

GETDATE and GETUTCDATE are some of the functions that are evaluated once per query: not per row or column in that query. The optimiser will ensure they are the same because it updates the values at the same time

Another option is to define a DEFAULT constraints so you can do this and worry less about it.

UPDATE dbo.MyTable
SET CreationDate = DEFAULT, ModifiedDate = DEFAULT, ...
...

I have tables with similar columns with DEFAULT constraints and never had an issue. This also means I never have to think about what function I use in code.

Edit:

I could be wrong: SQL Server: intrigued by GETDATE()

Or I could be right: Selecting GETDATE() function twice in a select list-- same value for both?

Article: Conor Cunnigham mentions it the behaviour

Edit2: I'm demonstratably wrong: see StriplingWarrior's self answer. It's evaluated per column (not per row and not per query)