Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Behaviour of SELECT @Var and SET @Var in T-SQL when dealing with NULLs

Tags:

sql

tsql

select

Everyday I learn something new, it seems :) Can someone please explain to me the rationale behind the following code behavior:

DECLARE @A INT

SET @A = 15
SET @A = (SELECT ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound')

SELECT @A
-- Rsultset is NULL

SET @A = 15
SELECT @A = ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound'

SELECT @A
-- Resultset is 15

From what I see, SET changes the value of the variable if the resultset is NULL, while SELECT doesn't. Is this normal ANSI behavior or is it T-SQL specific?

Of, course, if I do SELECT @A = NULL, the assignment happens correctly.

like image 876
cearny Avatar asked Sep 17 '12 07:09

cearny


People also ask

What is difference between SELECT and set?

SET is used to assign a value to a variable and SELECT is used to assign a value or to select value from a variable/table/view etc.

Can we use set with SELECT in SQL?

SET and SELECT may be used to assign values to variables through T-SQL. Both fulfill the task, but in some scenarios unexpected results may be produced. In this tip I elaborate on the considerations for choosing between the SET and SELECT methods for assigning a value to variable.

Can we use set in SELECT?

SET is the ANSI standard for variable assignment, SELECT is not. SET can only assign one variable at a time, SELECT can make multiple assignments at once. If assigning from a query, SET can only assign a scalar value. If the query returns multiple values/rows then SET will raise an error.

How do you set a variable value in a SELECT statement?

To assign a value to a variable, use the SET statement. This is the preferred method of assigning a value to a variable. A variable can also have a value assigned by being referenced in the select list of a SELECT statement.


2 Answers

The first version sets A to the result of a query:

SET @A = (SELECT ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound')

Basically the select in in scalar context, and if it doesn't find a row, it evaluates to null.

The second version sets A for each row in the result set:

SELECT @A = ValueThatDoesntExist FROM dbo.MyTable WHERE MyColumn = 'notfound'

Since there are no rows, A is never assigned to. Another example:

declare @a int

select  @a = i
from    (
        select  1
        union all select 2
        union all select 3
        ) as SubQueryAlias(i)
order by
        i

select  @a

This will assign 3 values to @a. The last one assigned is 3, so that's what the query prints.

like image 170
Andomar Avatar answered Oct 24 '22 18:10

Andomar


Well the select returns no rows. So practically there is not assignment.

While the set will have a null as a result.

like image 32
Dumitrescu Bogdan Avatar answered Oct 24 '22 20:10

Dumitrescu Bogdan