IsNull with Equal ¿What does this means? - sql-server

I have a basic question of SQL
What does the IsNull()=0 means in this code?
As far as I know, = assigns a value, but in this case it is used inside a Where statement.
Hope somebody can explain it to me :)
Where vol.espe_codigo = matriz.espe_codigo
And IsNull(costo_gerencias.plde_codigo,0) = 0

isnull(firstvalue, secondvalue) tests if the value for firstvalue is NULL or not. When the value is not null than this value is returned, but when the value is null than the value of secondvalue is returned.
Examples :
declare #test varchar(100) = 'abc'
declare #test2 varchar(100) = '123'
isnull(#test, #test2) will return 'abc'
second example :
declare #test varchar(100) = null
declare #test2 varchar(100) = '123'
isnull(#test, #test2) will return '123'
third example :
declare #test varchar(100) = ''
declare #test2 varchar(100) = '123'
isnull(#test, #test2) will return ''
I use it most to check on varchar columns, since they may contain an empty string which is not the same as NULL, but in a DataGridView or TextBox you cannot see the difference.

It means that if costo_gerencias.plde_codigo is null, it will return 0 or whatever the second argument is to the ISNULL function. In this case, the WHERE clause is basically saying "where vol.espe_codigo is equal to matriz.espe_codigo and costo_gerencias.plde_codigo is null or equal to zero."

IsNull() is a function which takes two input values of any type; however the second must be implicitly convertible to the type to the 1st parameter. (See link)
The database engine evaluates the first parameter and if it's null, the system returns the second parameter. If the 1st parameter is not null, it returns the value of the first parameter.
So in your case the engine will return the value 0 if plde_codigo is null. If not null it returns the value of plde_codigo passed in.
This in turn means your result set will only contain records which have a NULL or 0 value in plde_Codigo; in addition to other limiting criteria.
It could also be written as:
(costo_gerencias.plde_codigo is NULL OR costo_gerencias.plde_codigo = 0)
or to be more database agnostic:
coalesce(costo_gerencias.plde_codigo,0)=0
But in this case plde_codigo must be numeric; whereas it could be text when using isNull()

Related

Filter Null value based on condition in SQL Server [duplicate]

Could someone please explain the following behavior in SQL?
SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)
<> is Standard SQL-92; != is its equivalent. Both evaluate for values, which NULL is not -- NULL is a placeholder to say there is the absence of a value.
Which is why you can only use IS NULL/IS NOT NULL as predicates for such situations.
This behavior is not specific to SQL Server. All standards-compliant SQL dialects work the same way.
Note: To compare if your value is not null, you use IS NOT NULL, while to compare with not null value, you use <> 'YOUR_VALUE'. I can't say if my value equals or not equals to NULL, but I can say if my value is NULL or NOT NULL. I can compare if my value is something other than NULL.
NULL has no value, and so cannot be compared using the scalar value operators.
In other words, no value can ever be equal to (or not equal to) NULL because NULL has no value.
Hence, SQL has special IS NULL and IS NOT NULL predicates for dealing with NULL.
Note that this behavior is the default (ANSI) behavior.
If you:
SET ANSI_NULLS OFF
http://msdn.microsoft.com/en-us/library/ms188048.aspx
You'll get different results.
SET ANSI_NULLS OFF will apparently be going away in the future...
We use
SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';
to return all rows where MyColumn is NULL or all rows where MyColumn is an empty string. To many an "end user", the NULL vs. empty string issue is a distinction without a need and point of confusion.
In SQL, anything you evaluate / compute with NULL results into UNKNOWN
This is why SELECT * FROM MyTable WHERE MyColumn != NULL or SELECT * FROM MyTable WHERE MyColumn <> NULL gives you 0 results.
To provide a check for NULL values, isNull function is provided.
Moreover, you can use the IS operator as you used in the third query.
The only test for NULL is IS NULL or IS NOT NULL. Testing for equality is nonsensical because by definition one doesn't know what the value is.
Here is a wikipedia article to read:
https://en.wikipedia.org/wiki/Null_(SQL)
NULL Cannot be compared to any value using the comparison operators. NULL = NULL is false. Null is not a value. The IS operator is specially designed to handle NULL comparisons.
null represents no value or an unknown value. It doesn’t specify why there is no value, which can lead to some ambiguity.
Suppose you run a query like this:
SELECT *
FROM orders
WHERE delivered=ordered;
that is, you are looking for rows where the ordered and delivered dates are the same.
What is to be expected when one or both columns are null?
Because at least one of the dates is unknown, you cannot expect to say that the 2 dates are the same. This is also the case when both dates are unknown: how can they be the same if we don’t even know what they are?
For this reason, any expression treating null as a value must fail. In this case, it will not match. This is also the case if you try the following:
SELECT *
FROM orders
WHERE delivered<>ordered;
Again, how can we say that two values are not the same if we don’t know what they are.
SQL has a specific test for missing values:
IS NULL
Specifically it is not comparing values, but rather it seeks out missing values.
Finally, as regards the != operator, as far as I am aware, it is not actually in any of the standards, but it is very widely supported. It was added to make programmers from some languages feel more at home. Frankly, if a programmer has difficulty remembering what language they’re using, they’re off to a bad start.
I would like to suggest this code I made to find if there is a change in a value,
i being the new value and d being the old (although the order does not matter). For that matter, a change from value to null or vice versa is a change but from null to null is not (of course, from value to another value is a change but from value to the same it is not).
CREATE FUNCTION [dbo].[ufn_equal_with_nulls]
(
#i sql_variant,
#d sql_variant
)
RETURNS bit
AS
BEGIN
DECLARE #in bit = 0, #dn bit = 0
if #i is null set #in = 1
if #d is null set #dn = 1
if #in <> #dn
return 0
if #in = 1 and #dn = 1
return 1
if #in = 0 and #dn = 0 and #i = #d
return 1
return 0
END
To use this function, you can
declare #tmp table (a int, b int)
insert into #tmp values
(1,1),
(1,2),
(1,null),
(null,1),
(null,null)
---- in select ----
select *, [dbo].[ufn_equal_with_nulls](a,b) as [=] from #tmp
---- where equal ----
select *,'equal' as [Predicate] from #tmp where [dbo].[ufn_equal_with_nulls](a,b) = 1
---- where not equal ----
select *,'not equal' as [Predicate] from #tmp where [dbo].[ufn_equal_with_nulls](a,b) = 0
The results are:
---- in select ----
a b =
1 1 1
1 2 0
1 NULL 0
NULL 1 0
NULL NULL 1
---- where equal ----
1 1 equal
NULL NULL equal
---- where not equal ----
1 2 not equal
1 NULL not equal
NULL 1 not equal
The usage of sql_variant makes it compatible for variety of types
NULL is not anything...it is unknown. NULL does not equal anything. That is why you have to use the magic phrase IS NULL instead of = NULL in your SQL queries
You can refer this: http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx

DECLARE #bitVariable BIT NOT NULL -- how (MS SQL) [duplicate]

In T-SQL, I declare a local variable for use with some query like so:
DECLARE #var_last datetime;
SET #var_last = (SELECT TOP(1) col_date FROM tbl_dates ORDER BY col_date);
In an application I'm testing, it would be an error for this query to return NULL, and it's desirable for the query to return a crash error if it were.
I'd like to set #var_last to be NOT NULL but the syntax...
DECLARE #var_last datetime NOT NULL;
...is invalid. I can write a simple check on the return of the query to see if it's NULL, and error if it is, but my question is, is it not possible to declare a local variable as NOT NULL?
That's right, according the documentation for the DECLARE #local_variable, available at: http://technet.microsoft.com/en-us/library/ms188927.aspx, it doesn't accept a NULL | NOT NULL parameter -- those are only valid for column definitions.
If you want to stop execution if you return a NULL, then test for NULL and, if it is, RAISERROR; see: http://technet.microsoft.com/en-us/library/ms178592.aspx.
You can do something like this ...
Using ISNULL()
SELECT TOP(1) #var_last = ISNULL(col_date,'19000101') --<-- Some default value
FROM tbl_dates
ORDER BY col_date;
Using COALESCE()
SELECT TOP(1) #var_last = COALESCE(col_date,'19000101') --<-- Some default value
FROM tbl_dates
ORDER BY col_date;
It is not possible to set a variable to NOT NULL because NULL and NOT NULL are states, not values (even tho you can set a variable to NULL which looks like you are setting a value but you are actually erasing the existing value).
NULL, by definition, means has no value.

How to hold values in variable in sql server

I need to fetch max length of First_name and put it into #sq i am getting an error.
Declare #sq nvarchar(max)
Set #sq=''
SELECT MAX(LEN(FIRST_NAME)) FROM #table1
Drop table #t
SELECT CASE WHEN LEN(SEQ_NUM) = 0 THEN NULL ELSE SEQ_NUM END AS REC_NUM,
CASE WHEN LEN(FIRST_NAME) = 0 THEN NULL ELSE CONVERT(CHAR(Select #sq)),RTRIM(UPPER(FIRST_NAME))) END AS FIRST_NAME
into #t
from #tabel1
There's a few problem with this SQL. If we start with the first statement:
Set #sq=''SELECT MAX(LEN(FIRST_NAME)) FROM #table1
You have a couple of wayward single quotes here ('); not sure what they're doing. Secondly, if you're assigning a variables value from a dataset, the syntax is SELECT {Variable} = {expression} [,{Variable} = {expression} [,...]] FROM {etc} Thus you get:
SELECT #sq = MAX(LEN(FIRST_NAME))
FROM #table1;
The next statement, well, that's a mess. Firstly, there's also a wayward right parenthesis ()) here: RTRIM(UPPER(FIRST_NAME))) There should only be 2.
The expression CONVERT(CHAR(Select #sq)) is very wrong. CONVERT require 2 parameters, but only has one, and CHAR would return an character for the appropriate number provided. I.e. CHAR(65) returns A. I suspect you mean CONVERT(char,#sq) (you should really be declaring a length here!), however, #sq is already an nvarchar(max) (which is also pointless, as it's being assigned the value of an int). Thus I literally have no idea what you're trying to achieve here.
You need to assign the variable, like this:
Declare #sq int --LEN returns an int, not a varchar!
SELECT #sq = MAX(LEN(FIRST_NAME))
FROM #table1

SQL Nested Case Statements Within Stored Proc

I'm having problems getting back the data I'd expect from a stored procedure. The procedure is used to both insert and update record, and this determines which parameters are set when called. My example here is assuming the DATE type parameter has the default value of NULL, i.e. they have not been passed into the sp. I have broken the code down into a small section to fix, rather than include the entire procedure code, as follows:
-- these would be sp parameters
declare #CustomerId int = 15
declare #Indicator varchar(5) = 'Yes'
declare #ProjectTypeId tinyint = 1
declare #FutureEffectiveDate as date = null
SELECT
CASE #FutureEffectiveDate
WHEN NULL THEN
CASE #Indicator
WHEN 'Yes' THEN
-- can only be 1, 2 or 3 to return relevant date
CASE #ProjectTypeId
WHEN 1 THEN DI.[NextFormalEffectiveDate]
WHEN 2 THEN DI.[NextInterimEffectiveDate]
WHEN 3 THEN DI.[NextAccountingEffectiveDate]
END
-- data should be NULL if #Indicator not 'Yes'
ELSE NULL
END
ELSE #FutureEffectiveDate
END AS [FutureEffectiveDate]
FROM
[_Staging].[DataImport_2] AS DI
JOIN
[CustomerView] AS CV ON CV.[CustomerNumber] = DI.[BillingInvoiced]
JOIN
[ProjectType] AS PT ON PT.[ProjectType] = DI.[ProjectType]
WHERE
CV.[CustomerID] = #CustomerId AND
PT.[ProjectTypeID] = #ProjectTypeId
So the idea is that, for records where a field contains the text 'Yes', and based on the project type for that record, it selects one of three dates. If the field is not 'Yes' then it should return NULL, ignoring the project type. If the date parameter is NOT null, then it should simply return the parameter passed in. The result is returned as the column 'FutureEffectiveDate'. With the example data I have, I would expect a date to be returned as the relevant field is 'Yes', and the column NextFormalEffectiveDate has a value (as project type is 1).
Oddly enough, if you exclude the outer CASE statement, it works. So the issue is around determining what to do based on the DATE parameter, but i cannot see why the outer CASE statement is breaking the result.
The way you checked #FutureEffectiveDate for NULL in CASE statement is wrong. Here is a small demo
declare #FutureEffectiveDate as date = null
Select Case #FutureEffectiveDate when NULL then 1 else 0 end
The above query will result 0. Because the above CASE statement validates the input expression like #FutureEffectiveDate = NULL which will fail. NULL should be compared using IS operator
Here is the correct way to compare NULL
SELECT CASE
WHEN #FutureEffectiveDate IS NULL THEN
CASE ..

Can I declare a local variable not null?

In T-SQL, I declare a local variable for use with some query like so:
DECLARE #var_last datetime;
SET #var_last = (SELECT TOP(1) col_date FROM tbl_dates ORDER BY col_date);
In an application I'm testing, it would be an error for this query to return NULL, and it's desirable for the query to return a crash error if it were.
I'd like to set #var_last to be NOT NULL but the syntax...
DECLARE #var_last datetime NOT NULL;
...is invalid. I can write a simple check on the return of the query to see if it's NULL, and error if it is, but my question is, is it not possible to declare a local variable as NOT NULL?
That's right, according the documentation for the DECLARE #local_variable, available at: http://technet.microsoft.com/en-us/library/ms188927.aspx, it doesn't accept a NULL | NOT NULL parameter -- those are only valid for column definitions.
If you want to stop execution if you return a NULL, then test for NULL and, if it is, RAISERROR; see: http://technet.microsoft.com/en-us/library/ms178592.aspx.
You can do something like this ...
Using ISNULL()
SELECT TOP(1) #var_last = ISNULL(col_date,'19000101') --<-- Some default value
FROM tbl_dates
ORDER BY col_date;
Using COALESCE()
SELECT TOP(1) #var_last = COALESCE(col_date,'19000101') --<-- Some default value
FROM tbl_dates
ORDER BY col_date;
It is not possible to set a variable to NOT NULL because NULL and NOT NULL are states, not values (even tho you can set a variable to NULL which looks like you are setting a value but you are actually erasing the existing value).
NULL, by definition, means has no value.

Resources