Reputation: 171
I came across a bug where I was using CAST(Col1 AS INT) + CAST(Col2 AS INT)
where both Col1 and Col2 are VARCHAR
and I was getting valid results out when Col1 or Col2 was blank and I didn't expect this. I checked and CAST (and CONVERT) both have this default behavior of replacing blank with 0:
SELECT CAST('' AS INT)
SELECT CONVERT(INT, '')
I checked the info page and I can't see any reference to explain why this is the behavior (or change it through a server setting). I can of course work around this but I wanted to ask why this is the behavior as I do not think it is intuitive.
I'd actually rather this CAST
failed or gave NULL
, is there a server setting somewhere which effects this?
Upvotes: 15
Views: 107161
Reputation: 632
What about this ?
declare @t table(bucket bigint);
INSERT INTO @t VALUES (1);
INSERT INTO @t VALUES (2);
INSERT INTO @t VALUES (-1);
INSERT INTO @t VALUES (5);
INSERT INTO @t VALUES (0);
declare @Bucket bigint = 0 --filter by 0
select * from @t
where 1=1
AND ((@Bucket is Null or cast(@Bucket as nvarchar) = '') or bucket=@Bucket)
Upvotes: 0
Reputation: 22733
Consider an INT
in SQL Server. It can be one of three values:
So if you're casting/converting an empty string, which you are assuming is a number, then 0 is the most logical value. It allows for a distinction between NULL and 0.
SELECT CAST(NULL AS INT) -- NULL
SELECT CAST('' AS INT) -- 0
SELECT CAST('42' AS INT) -- 42
I'd say that's logical.
If you did:
SELECT CAST('abc' AS INT)
You'd get:
Conversion failed when converting the varchar value 'abc' to data type int.
If you do wish to handle empty strings as NULL
use NULLIF as Bogdan suggests in his answer:
DECLARE @val VARCHAR(2) = ''
SELECT CAST(NULLIF(@val,'') AS INT) -- produces NULL
NULLIF returns the first expression if the two expressions are not equal. If the expressions are equal, NULLIF returns a null value of the type of the first expression.
Finally, if your columns are storing INT
values, then consider changing its data type to INT
if you can.
Upvotes: 23
Reputation: 15977
As you probably know NULL
is a marker that indicates that a data value does not exist. And ''
is a value, empty but value.
So MS SQL cast (or converts) empty value into 0
by default. To overcome this and show it as NULL
you can use NULLIF
Simple example:
SELECT int_as_varchars as actual,
cast(NULLIF(int_as_varchars,'') as int) as with_nullif,
cast(int_as_varchars as int) as just_cast
FROM (VALUES
('1'),
(''),
(NULL),
('0')
) as t(int_as_varchars)
Output:
actual with_nullif just_cast
1 1 1
NULL 0
NULL NULL NULL
0 0 0
As you see NULLIF in that case will help you to get NULL
instead of 0
.
Upvotes: 0