T-SQL unexpected behavior in isnull function - sql-server

When i run this query i expect the result will be 'false'
IF isnull(0,'') = ''
select 'true'
else
select 'false'
But sql Server tells me 'true', why?

In this case ISNULL(0,'') returns an integer. SQL Server will cast the second argument to an integer too, ie 0. So 0=0, hence the result is TRUE. Comparing directly to 0 would also return true:
IF 0 = ''
select 'true'
else
select 'false'
Using ISNULL and NULL like this is unusual. An ISNULL(someColumn='') function in a WHERE clause would prevent the optimizer from using any indexes that covered someColumn thus forcing a scan instead of an index seek.
Using IF statements in SELECT is impossible. Even in CASE statements, it's better to explicitly check for NULL than apply such transformations.

For your case, when compare two values, the '' will be converted to int first. The following:
SELECT CONVERT(INT, '')
returns 0, so 0=0 is true
If you want treat 0 as NULL, you can use NULLIF:
DECLARE #i INT = 0
IF NULLIF(ISNULL(#i, ''), 0) = ''
SELECT 'true'
ELSE
SELECT 'false'
This would return 'false'

ISNULL are identical when there are just two values (i.e. NULL and 0) so, it will be true in IF condition and select 'true' will be printed.

Related

T-SQL Variable in Where clause

I want to return the records in this case that have company ABC... and contact is null. It will not return anything when #Contact is null. Or any variable for that matter. Ideas?
DECLARE #Customer NVARCHAR(40) = 'ABC Company',
#Contact NVARCHAR(40) = NULL
SELECT
Company
FROM
company
WHERE
contact = #Contact AND customer = #Customer
Thanks,
EB
NULL is special in that it means UNKNOWN.
A known value (contact) can never equal an unknown value. You need an OR statement to check if it's equal OR is null
where (contact = #Contact OR (contact is null AND #Contact is null))
and customer = #Customer
Maybe something like that?
you can write
WHERE
ISNULL(contact,'') = ISNULL(#Contact,'') AND customer = #Customer
this do a null check and if null,then value will be considered as empty string for comparison.
instead of null==null (Which gives false), ''=='' will be performed.
if(null =null)
print 'Equal'
else
print 'not equal'
/*******************************************/
if('' ='')
print 'Equal'
else
print 'not equal'
In SQL, there is trivalent logic applied. In this reference you can read in detail about such logic. Bottom line is, that among true and false, there is another value: UNKNOWNN, which (in SQL) is the result of comparisons with NULL values. You can think of it as false (in this case).
Now, to visualise:
this queries won't return anything, as the where clause evaluates to UNKNOWN:
select 1 where null = 0
select 1 where null <> 0
select 1 where null = null
While this might be obvious, there's consequence: when you use not in operator.
When right operand contains NULLs, the query will return no records, e.g.:
select 1 where 0 not in (null, 1, 2)
won't return anything. It's especially important when you put some query as right operand.

How to compare different values in sql server

I must to check if two values, X and Y are different. If both are null, they must be considered as equal.
The unique way I found is:
select 1 as valueExists
where (#X is null and #Y is not null)
or (#Y is null and #X is not null)
or (#X <> #Y)
Is there a smart way to write this expression?
Thanks!
I think you could use COALESCE for that
WHERE coalesce(#X, '') <> coalesce(#Y, '')
What it does it returns an empty string if one of variables is null, so if two variables are null the two empty strings become equal.
I typically use a technique I picked up from here
SELECT 1 AS valuesDifferent
WHERE EXISTS (SELECT #X
EXCEPT
SELECT #Y)
WHERE EXISTS returns true if the sub query it contains returns a row. This will happen in this case if the two values are distinct. null is treated as a distinct value for the purposes of this operation.
You could try using NULLIF like this:
WHERE NULLIF(#X,#Y) IS NOT NULL OR NULLIF(#Y,#X) IS NOT NULL
You can use ISNULL
WHERE ISNULL(#X,'') <> ISNULL(#Y,'')

SQL Server 2008 Case When Cast

I'm having trouble figuring this statement out. It seems that SQL Server is still executing the THEN part in the CASE WHEN statement. Please see this query.
SELECT
CASE
WHEN ISNUMERIC('INC') = 1
THEN CAST('INC' as numeric(10,2))
ELSE 'FALSE'
END AS foo
SQL Server is returning
"Error converting data type varchar to numeric"
From this query it should return FALSE and not return an Error since the THEN part was not executed.
What is wrong with my query?
The problem is that you are returning two different data types from the same column. So try this one -
DECLARE #value CHAR(3)
SET #value = 66
SELECT
CASE WHEN ISNUMERIC(#value) = 1
THEN CAST(CAST(#value AS NUMERIC(10,2)) AS VARCHAR(30))
ELSE 'FALSE'
END AS foo
That is because, your query is trying to
CAST 'FALSE' as Numeric(10,2)
Try this
SELECT CASE WHEN ISNUMERIC('INC') = 1 THEN
CAST(CAST('INC' as numeric(10,2)) AS varchar(5))
ELSE 'FALSE' END AS foo
The problem is that one branch of you CASE branches returns VARCHAR and the other a number.
Try the following:
CASE WHEN ISNUMERIC('INC') = 1
THEN CAST(CAST('INC' AS NUMERIC(10,2)) AS NVARCHAR)
ELSE 'FALSE'
END AS foo

How to check if bit variable is true or false in sql server?

I have a simple query and all I want to do is check if this variable is true or false, and for some reason it always returns false.
DECLARE #CappedIFCheck BIT
SET #CappedIFCheck = (SELECT distinct 1
FROM mytable
WHERE 1=1);
select #CappedIFCheck
IF (#CappedIFCheck = 'True')
BEGIN
SELECT 'true';
END
ELSE
BEGIN
SELECT 'false';
END
When comparing BIT values in Sql Server, use literal values 1 and 0 instead of 'True' and 'False'.
IF (#CappedIFCheck = 1) ...
A bit variable in SQL Server can have three values. 0, 1 and NULL.
The strings 'true' and 'false' map to 1 and 0 respectively.
Your code does not take account of the third possible value. If mytable is empty then the variable will not be initialised and have the value NULL.
SELECT CASE #CappedIFCheck
WHEN 'True' THEN 'true'
WHEN 'False' THEN 'false'
ELSE 'unknown'
END
I'm not sure exactly what your code is trying to do but that is a very inefficient way of going about things. You should use EXISTS instead.
Try the set clause like this:
SET #CappedIFCheck = ISNULL((select 1 where exists (select 1 from MyTable where 1=0)),0)

Is it possible to convert nvarchar to int?

I have tried something like this:
select PREPRO = case when (isnumeric(PREPRO) = 1 and
PREPRO in ('0','1','-1')) or
convert(varchar, PREPRO) in ('True','False')
then convert(bit, convert(integer, PREPRO)) else 'No' end
from dbo.TI10SE
The PREPRO contains all "False".
I get this error:
Conversion failed when converting the nvarchar value 'False' to data type int.
Does it mean that an nvarchar can not be converted to an integer ever? I guess its because some data may be lost.
You are trying to convert your PREPRO to an integer, even if the value it holds is True or False:
convert(integer, PREPRO)
You cannot convert the value False to an integer.
The conditional in your when clause evaluates to true when PREPRO is a number within 0, 1, -1 OR when it evaluates to either True or False. In any of these cases, you attempt to convert this value to an integer and then to a bit.
Use CASE to accomplish this:
DECLARE #PREPRO VARCHAR(5)
SET #PREPRO = 'False'
SELECT CASE WHEN #PREPRO = 'False' THEN 0 ELSE 1 END
nvarchar can be converted to an integer if it contains an integer
DECLARE #PREPRO VARCHAR(5)
SET #PREPRO = '10'
SELECT CONVERT(integer, #PREPRO)
T-SQL doesn't know what to associate with 'False' or 'True', so you will have to use a CASE statement like rdkleine said.
Also in this statement:
convert(bit, convert(integer, PREPRO)) else 'No' end
You're going to receive an error, because 'No' is not of type bit, what are you trying to return?

Resources