A co-worker of mine stated that she have a query that "work" only if she use NULL, and not with null.
She wasn't able to provide me with an example.
As far as I know there shouldn't be any difference, I even ran a simple test:
select case when NULL is NULL then 1 else 0 end;
select case when NULL is null then 1 else 0 end;
select case when null is NULL then 1 else 0 end;
select case when null is null then 1 else 0 end;
and, as expected, they all returned 1.
So here the question, there is any know istance where using null is different than using NULL?
maybe she compared strings 'NULL' and 'null'
Yes:
is NULL and is null produces the same result its case insenstive
Related
In stored procedure I have this query
DECLARE #BadRowsCount int;
SET #BadRowsCount = 0;
SELECT #BadRowsCount = COUNT(*)
FROM #ImportTemp
WHERE #ImportTemp.Status <> 'A' AND #ImportTemp.Status <> 'B'
And #BadRowsCount if in #ImportTemp.Status are values different than A or B has positive value that is ok.
But if in #ImportTemp.Status is NULL #BadRowsCount is 0.
Why? NULL isn't different than A or B?
Status is defined as:
[Status] [varchar](80) NULL
I must define WHERE clause like:
WHERE (#ImportTemp.Status <> 'A' AND #ImportTemp.Status <> 'B') OR #ImportTemp.Status is NULL
?
By default, in SQL Server, comparison operators return UNKNOWN (i.e. not true or false) if either value is a null.
MSDN IS [NOT] NULL documentation
There are ways to change how SQL Server handles null comparisons with things like SET ANSI_NULLS. Definitely pay attention to upcoming changes to the default for this value.
Here is an interesting article which covers several issues related to null handling.
Because the not equal operator (<>) is, like most operators, not NULL save. That means it results in unknown when comparing with NULL.
I have the below Case Statment and I'm inserting this into a new table. The column under the new table is Varchar but I need it as an INT. I have changed the data type using the Alter statment but I frequenctly delete and create the same table. Is there a way to have the new table create the data type of INT instead of varchar for the below syntax?
CASE WHEN F.END_DATE IS NOT NULL OR F.REASON IS NOT NULL THEN '0' ELSE '1' END Enrolled'
Get rid of the single quotes around 0 and 1:
CASE WHEN F.END_DATE IS NOT NULL OR F.REASON IS NOT NULL THEN 0 ELSE 1 END Enrolled'
Try Following:
CASE WHEN coalesce(F.END_DATE,F.REASON ,0)=0 THEN 0 ELSE 1 END Enrolled
I have the following code:
declare #testValue nvarchar(50) = 'TEST';
select #testValue = 'NOTUSED' where 1 > 2;
select #testValue; -- Outputs 'TEST'
select #testValue = 'USED' where 2 > 1;
select #testValue; -- Outputs 'USED'
With the above, the first assignment is never used because the where clause fails. The second one is done properly and used is returned.
Why doesn't SQL return a null in this case and assigns a NULL value to #testValue after the first assignment where the where clause fails?
This is the expected behavior:
"If the SELECT statement returns no rows, the variable retains its present value. If expression is a scalar subquery that returns no value, the variable is set to NULL."
https://msdn.microsoft.com/en-us/library/ms187330.aspx
You can get around this in your example by using a subquery in the right side.
SELECT #testValue = (SELECT 'NOTUSED' where 1 > 2);
As for why it is this way, I cannot say for certain. Perhaps the entire #testValue = 'NOTUSED' is equating to NULL instead of only the right side 'NOTUSED' portion of the statement, and this prevents the parameter from being set. Not directly related but I can say it took me some time to grow confident with writing queries when NULLs are involved. You need to be aware of / familiar with the ANSI NULL spec and associated behavior.
This is the default behavior of SELECT.
When assigning a value to a variable using SELECT, if there is no value returned, SELECT will not make the assignment at all so the variable's value will not be changed.
On the other hand, SET will assign NULL to the variable if there is no value returned.
For more info
NULL is the ideal value you would like but the SQL engine is not clever enough, because some else may want empty string , ' ' in that situation or 0 or 1, you see. So no single default value is set. Best is set your own default value. You can see below
DECLARE #testValue NVARCHAR(50) = 'TEST';
SELECT #testValue = 'NOTUSED' WHERE 2 > 1;
IF 2 <> 1
SELECT #testValue = NULL;
SELECT #testValue; -- Outputs 'TEST'
SELECT #testValue = 'USED' WHERE 1 > 2;
SELECT #testValue; -- Outputs 'USED'
NULL in SQL is used to denote missing data or an unknown value. In this case the data is not missing, the value of #testValue is known, it is just failing an assignment condition, so it gets no new value.
If you were to change your initial assignment to be like this
declare #testValue nvarchar(50)
You would get NULL like below :
select #testValue = 'NOTUSED' where 1 > 2;
select #testValue; -- Outputs NULL
select #testValue = 'USED' where 2 > 1;
select #testValue; -- Outputs 'USED'
Don't be too disappointed your not getting NULL back in the your example. NULL is not easy to handle.
For example, you can not compare two NULL values, because instances of NULL are not equal. Consequently you also need to use special operators like ISNULL to check for it.
In general, NULL as a programming construct should be avoided in my opinion. This is a bit of area of contention across the programming languages. But consdier this, even the creator of null Tony Hoare, calls the creation of null his 'billion dollar mistake'.
I know that in SQL when we compare two NULL values, result is always false. Hence, statements like
SELECT case when NULL = NULL then '1' else '0' end
will always print '0'. My question is how functions like ISNULL determine whether value is null or not. Because, as per my understanding (and explained in above query) comparison of two null values is always FALSE.
You need to set the set ansi_nulls off and then check your result. Null can be thought of as an unknown value and when you are comparing two unknown values then you will get the result as false only. The comparisons null = null is undefined.
set ansi_nulls off
SELECT case when NULL = NULL then '1' else '0' end
Result:-
1
From MSDN
When SET ANSI_NULLS is OFF, the Equals (=) and Not Equal To (<>)
comparison operators do not follow the ISO standard. A SELECT
statement that uses WHERE column_name = NULL returns the rows that
have null values in column_name. A SELECT statement that uses WHERE
column_name <> NULL returns the rows that have nonnull values in the
column. Also, a SELECT statement that uses WHERE column_name <>
XYZ_value returns all rows that are not XYZ_value and that are not
NULL.
As correctly pointed by Damien in comments the behavior of NULL = NULL is unknown or undefined.
Your initial assumption appears to be that ISNULL is an alias for existing functionality which can be implemented directly within SQL statements, in the same way that a SQL function can. You are then asking how that function works.
This is an incorrect starting point, hence the confusion. Instead, like similar commands such as IN and LIKE, ISNULL is parsed and run within the database engine itself; its actual implementation is most likely written in C.
If you really want to look into the details of the implementation, you could take a look instead at mySQL - it's open source, so you may be able to search through the code to see how ISNULL is implemented there. They even provide a guided tour of the code if required.
... or {2} are you literally asking how the ISNULL function in SQL
Server itself works?
Actually I am asking for the second{2}. How ISNULL function in SQL server
works. If comparison of two nulls is not defined/unknown then how
isnull function compares two null values to return appropriate
results?
Null is a special marker used in Structured Query Language (SQL) to indicate that a data value does not exist in the database. ... NULL (SQL)
ISNULL ( check_expression , replacement_value ) is not concerned with comparison of values at all. It is concerned purely with the existence of value in the first parameter.
It tests if the check_expression has any value. If it does have any value that value is returned. If check_expression has no value the ISNULL function returns the second parameter replacement_value.
It does NOT compare the two values. It tests forthe existence of value in the first parameter only.
set ansi_nulls off
SELECT case when NULL = NULL then '1' else '0' end
result=1
set ansi_nulls on
SELECT case when NULL = NULL then '1' else '0' end
result=0
so that is the difference
I hope it works
SELECT CASE WHEN ISNULL(NULL,NULL) = NULL THEN 1 ELSE 0 END
SELECT case when 'NULL' = 'NULL' then '1' else '0' end
SELECT case when isnull(columnname,'NULL')='NULL' then '1' else '0' end
SET ANSI_NULLS OFF
SELECT case when NULL = NULL then '1' else '0' end
I've created the following stored procedure:
ALTER PROCEDURE [dbo].[ExampleSP]
(
#SearchText NVARCHAR(4000),
#ID INT = NULL
)
AS
BEGIN
SET NOCOUNT ON;
SELECT
deID,
deTitle
FROM tblDemo As de
LEFT JOIN tblLinkTable As lnk ON (lnk.ID = de.deID)
WHERE CONTAINS(cstKeywords, #SearchText)
AND ((#ID IS NULL) OR (lnk.ID = #ID))
GROUP BY deID,Title
ORDER BY de.Title
But I also need to be able to find the first field that is not null out of the following table columns:
deIntroText, deCompanyText, deTimetableText and deExampleText
And i need to do this for each record that is returned from the SELECT.
So I realise that i'd need to create a temporary column to store it in and i guess you'd need to use an IF statement like this:
IF deIntroText IS NOT Null
THEN TempFieldToReturn = 1
ELSE IF deCompanyText IS NOT Null
THEN TempFieldToReturn = 2
ELSE IF deTimetableText IS NOT Null
THEN TempFieldToReturn = 3
ELSE IF deExampleText IS NOT Null
THEN TempFieldToReturn = 4
So my question is - what is the best way to achieve this? Any examples would be appreciated.
No real shortcut - just use a CASE expression:
SELECT
/* Other Columns */
CASE
WHEN deIntroText IS NOT Null THEN 1
WHEN deCompanyText IS NOT Null THEN 2
WHEN deTimetableText IS NOT Null THEN 3
WHEN deExampleText IS NOT Null THEN 4
ELSE 5 END as OtherColumn
FROM
/* Rest of query */
This is a Searched CASE - there are actually two variants of CASE. I guessed at 5 if all of the columns are NULL - you might leave off the ELSE 5 portion, if you want a NULL result in such a case.