Reputation: 43626
It is a well known practice to this:
DECLARE @A INT
,@B INT
SELECT @A = [Column01]
,@B = [Column02]
FROM [dbo].[data]
I am wondering is it true for the following code:
DECLARE @A INT
,@B INT
SELECT @A = [Column01]
,@B = @A + [Column02]
FROM [dbo].[data]
that @A
is always getting value before @B
?
In my real case [Column01]
and Column02
are an expressions with many columns and T-SQL
functions and using @A
as reference is simplifying the initialization of @B
.
Upvotes: 3
Views: 2762
Reputation: 6002
In my experience so far this has always worked 'top down' for me. However, I too feel a bit queasy whenever I write something like that and have been known to split it into two separate commands when I had a more paranoid day, maybe I should have more of those =)
That said, the question could be extended to these syntaxes of which I 'assume by experience' they are correct but again wonder if anyone has a more definite answer to it :
DECLARE @a int,
@b int,
@x int
SELECT @a = (CASE name WHEN 'A' THEN value ELSE @a END),
@b = (CASE name WHEN 'B' THEN value ELSE @b END)
FROM myTable
WHERE name IN ('A', 'B')
which gives the same result as below but is quite a bit faster, especially if you have to fetch many of them
SELECT @a = value FROM myTable WHERE name = 'A'
SELECT @b = value FROM myTable WHERE name = 'B'
Or, this one:
DECLARE @a int = 8,
@b int = 5,
@x int
UPDATE myTable
SET @x = @a * leftField + @b * rightField,
mySum = @x,
mySquare = Power(@x, 2)
WHERE ...
Where I use @x to calculate an intermediate value for a given record and use said value later on to set a field or as part of a formula again. (I agree it's a stupid example but right now can't come up with something more sensible)
Or this one that now seems to be generally accepted as 'OK', but I do remember the days when this would go haywire if you'd add an ORDER BY
to it, which is often a requirement.
DECLARE @a varchar(max)
SELECT @a = (CASE WHEN @a IS NULL THEN name ELSE @a + ',' + name END)
FROM sys.objects
WHERE type = 'S'
SELECT @a
UPDATE: these things (likely) usually work fine as long as the datasets are small but odd things start to happen when the size of the data grows and the QO decides to use a different plan using multi-threading etc... So I tried to 'break' things by setting up a largish table that would no longer fit in memory and then see what would happen. I took a simple example that could easily be split into multiple threads. The result can be found here but you'll need to adapt it to your hardware off course (please don't put sqlFiddle to its knees!). The results so far are that things keep working but the query plans differ depending on the query we run (with or without @x and @y) !
Upvotes: 1
Reputation: 7036
that @A is always getting value before @B?
The answer is no.
Quoted from Itzik Ben-Gan's Microsoft SQL Server 2012 T-SQL Fundamentals
SQL supports a concept called all-at-once operations, which means that all expressions that appear in the same logical query processing phase are evaluated logically at the same point in time.
Please also check All-at-Once Operations in T-SQL
Upvotes: 3