Quantcast
Channel: Brent Ozar Unlimited®
Viewing all articles
Browse latest Browse all 3153

There’s Something Funny About Variable Assignment

$
0
0

Guess who

I’m going to give you three queries, and you have to guess what the output will be before you run them.

Here they are:

DECLARE @DatabaseName NVARCHAR(256) = N''

SELECT @DatabaseName = d.name
FROM sys.databases d
WHERE d.name = 'master' 
AND compatibility_level = 130
ORDER BY d.database_id

PRINT @DatabaseName

SELECT @DatabaseName = d.name
FROM sys.databases d
WHERE d.name = 'master' 
AND compatibility_level = -2147483647
ORDER BY d.database_id

PRINT @DatabaseName

SELECT @DatabaseName = d.name
FROM sys.databases d
WHERE d.name = 'tempdb' 
AND compatibility_level = 130
ORDER BY d.database_id

PRINT @DatabaseName

Go ahead

Feel free to sub in the compatibility level that your databases are actually in before running these on your own server.

I promise, they won’t bite.

But let’s talk about your guesses first!

Will it return…
master
tempdb

Or

master
master
tempdb

You have to pick one before you run it.

Hardweirded

If you guessed two masters, congratulations! You’re smarter than I was a few days ago.

While working on a script, I ran across a weird bug in it. Whatever database was processed last would get processed over and over again until another database was ready.

Picture having 5 databases — on the first run, the loop would hit database 5 and process database 5 several times. On the second loop, it would happen with database 4, and so on, then repeat.

I couldn’t figure out why at first, but then it hit me — the variable wasn’t resetting when it hit a NULL value! It only reset when it hit an actual value. I had to hard code a reset to NULL in between runs.

SET vs. SELECT

I could have avoided some of this trouble by using SET instead. There are some basic differences between the two, but this is an important one.

If I replace my code with this, it correctly assigns the NULL and returns nothing.

DECLARE @DatabaseName NVARCHAR(256) = N''

SET @DatabaseName =
(SELECT TOP 1 d.name
FROM sys.databases d
WHERE d.name = 'master' 
AND compatibility_level = -2147483647
ORDER BY d.database_id)

PRINT @DatabaseName

Thanks for reading!

It's the last week to save $1,000 on our new online classes with coupon code JoinOnline.


Viewing all articles
Browse latest Browse all 3153

Trending Articles