Further readingSee also my article, Fun with Scalar and Vector Aggregates
Multiple Definite Assignment
On occasion, you might need to definitely assign multiple variables at once. This means you have to use SELECT, but this doesn't assign NULL if no rows are produced by the query:
DECLARE @T AS table ( a integer NOT NULL, b integer NOT NULL, c integer NOT NULL ); -- Original values DECLARE @a integer = 1, @b integer = 2, @c integer = 3; -- Multiple assignment SELECT @a = T.a, @b = T.b, @c = T.c FROM @T AS T; -- Values unchanged because no row found SELECT a = @a, b = @b, c = @c; Output:
| a | b | c |
|---|---|---|
| 1 | 2 | 3 |
The workaround is to use an OUTER APPLY:
-- Definite assignment workaround DECLARE @T AS table ( a integer NOT NULL, b integer NOT NULL, c integer NOT NULL ); -- Original values DECLARE @a integer = 1, @b integer = 2, @c integer = 3; SELECT @a = T.a, @b = T.b, @c = T.c FROM (VALUES(1/0)) AS D (dummy) OUTER APPLY ( SELECT TT.a, TT.b, TT.c FROM @T AS TT ) AS T; -- Values changed to NULL SELECT a = @a, b = @b, c = @c; Output:
| a | b | c |
|---|---|---|
| NULL | NULL | NULL |
The dummy table ensures a row always exists to cause variable assignment. The outer apply means the dummy row is unaffected when the target query produces no rows.
The intentional division by zero in the dummy table expression ensures you don't accidentally select that value. That column isn't projected in the example, so the optimizer removes it from the execution plan and no error occurs.





