Whilst experimenting with MSSQL I came across some behaviour I cannot explain.
I was looking at what happens to a NULL value when it is added to a varchar, and when I do the following query:
SELECT
ISNULL(NULL + ' ', 'test')
I get the result 'te'. Similarly if I change the word test for any other word I only get the first two letters. If I increase the number of spaces in the + ' ' I get extra letters in my result (so NULL + '[two spaces]' gives me 'tes'). Any ideas what is going on?
If I declare a variable and set it to NULL e.g.
DECLARE @testnull AS varchar(32)
SET @testnull = NULL
SELECT
ISNULL(@testnull + ' ', 'test')
then I get the result 'test' (as I would expect).
Basically, a variable width column (varchar) stores a bitmap that indicates null or not null. If it's null, then zero bytes are allocated for the varchar field and the bit gets flipped. For fixed width columns (char), the entire field is still allocated, with no data stored in it.
Difference between SQL Server ISNULL with IS NULL The ISNULL and IS NULL functions are both different in SQL Server. We use the ISNULL function when we have a need to replace the NULL values with a specified value. On the other hand, we use the IS NULL function when we want to identify NULL values in a table.
advantage that COALESCE has over ISNULL is that it supports more than two inputs, whereas ISNULL supports only two. Another advantage of COALESCE is that it's a standard function (namely, defined by the ISO/ANSI SQL standards), whereas ISNULL is T-SQL–specific.
Comparing COALESCE and ISNULL Data type determination of the resulting expression is different. ISNULL uses the data type of the first parameter, COALESCE follows the CASE expression rules and returns the data type of value with the highest precedence.
Use COALESCE
. ISNULL
takes the first NON-NULL data type, and in this case because it hasn't been declared, you get a VARCHAR(1)
for the NULL
and then it becomes a VARCHAR(2)
when you add the space (this is still NULL
when evaluated but SQL Server makes an assumption before that step). In some cases the default for varchar
without length is 1, and in others it is 30. I'll let you guess which one is being used here.
SELECT
ISNULL(NULL + ' ', 'test'), COALESCE(NULL + ' ', 'test');
Results:
---- ----
te test
You can see this explicitly by:
SELECT
x = ISNULL(NULL + ' ', 'test')
INTO #a1;
SELECT
x = COALESCE(NULL + ' ', 'test')
INTO #a2;
SELECT LEFT(t.name, 3), TYPE_NAME(c.user_type_id), max_length
FROM tempdb.sys.columns AS c
INNER JOIN tempdb.sys.tables AS t
ON c.[object_id] = t.[object_id]
WHERE t.name LIKE '#a[1-2]%';
Results:
--- ------- ----
#a1 varchar 2
#a2 varchar 4
In almost all cases, I prefer COALESCE
over ISNULL
. I explain why (and where the exceptions exist) in this tip:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With