Is there a opposite function to ISNULL in sql server? To do Is not null?
You have to use CASE
SELECT CASE WHEN Field IS NOT NULL
THEN 'something'
ELSE 'something else'
END
IS NOT NULL and ISNULL( str, NULL ) in WHERE clause
We found this to be an issue in Sql Server 2008 with no service packs installed. Try installing SP1 or SP2. In our case, the service pack resolved the issue.
SQL Server : ISNULL(compound NULL condition, 'a string') returns only the 1st character, under certain circumstance(s)
There are two parts to this problem, the first is the nature of the ISNULL
operator, it will use the datatype and length of the first argument. A simple example would be:
DECLARE @A CHAR(1) = NULL,
@B VARCHAR(MAX) = 'This is a test';
SELECT TOP 1 Test = ISNULL(@A, @B);
This returns T
and checking the execution plan XML we can see the implicit conversion of "This is a Test"
to CHAR(1)
:
<ScalarOperator ScalarString="isnull([@A],CONVERT_IMPLICIT(char(1),[@B],0))">
<Intrinsic FunctionName="isnull">
<ScalarOperator>
<Identifier>
<ColumnReference Column="@A" />
</Identifier>
</ScalarOperator>
<ScalarOperator>
<Convert DataType="char" Length="1" Style="0" Implicit="true">
<ScalarOperator>
<Identifier>
<ColumnReference Column="@B" />
</Identifier>
</ScalarOperator>
</Convert>
</ScalarOperator>
</Intrinsic>
</ScalarOperator>
Your example is not quite so straightforward since you don't have your types nicely defined like above, but if we do define the dataypes:
DECLARE @A VARCHAR(MAX) = 'a big old string',
@B VARCHAR(MAX) = 'needle',
@C VARCHAR(MAX) = 'haystack';
SELECT TOP 1 ISNULL(LEFT(@A, NULLIF(CHARINDEX(@B, @C), 0) - 1), @A);
We get the result as expected. So something else is happening under the hood. The query plan does not delve into the inner workings of the constant evaluation, but the following demonstrates what is happening:
SELECT Test = LEFT('a big old string', NULLIF(CHARINDEX('needle', 'haystack'), 0) - 1)
INTO #T;
SELECT t.name, c.max_length
FROM tempdb.sys.columns AS c
INNER JOIN sys.types AS t
ON t.system_type_id = c.system_type_id
AND t.user_type_id = c.user_type_id
WHERE [object_id] = OBJECT_ID(N'tempdb..#T');
----------------
name max_length
varchar 1
Basically, by using the SELECT INTO
sytax with your left expression shows that a when the NULL length is passed to LEFT
the resulting datatype is VARCHAR(1)
, however, this is not always the case. If I simply hard code NULL
into the LEFT
function:
SELECT Test = LEFT('a big old string', NULL)
INTO #T;
--------------------
name max_length
varchar 16
Then you get the length of the string passed, but a case expression that should be optimised away to the same thing, yields a length of 1 again:
SELECT TOP 1 Test = LEFT('a big old string', CASE WHEN 1 = 1 THEN NULL ELSE 1 END)
INTO #T;
----------------
name max_length
varchar 1
I suspect it is related to the default behaviour of VARCHAR
, where the default length is 1, e.g:
DECLARE @A VARCHAR = 'This is a Test';
SELECT Value = @A, -- T
MaxLength = SQL_VARIANT_PROPERTY(@A, 'MaxLength') -- 1
But I can't tell you why you would see different behaviour for NULL
and CASE WHEN 1 = 1 THEN NULL ELSE 1 END
. If you wanted to get the bottom of what is going on in the constant evaluation I think you would probably need to re-ask on the DBA site and hope that one of the real SQL Server Gurus picks it up.
In summary, LEFT(<constant>, <constant expression>)
where <constant expression>
yields NULL
is implicitly typed as VARCHAR(1)
, and this implicit type is used in ISNULL
evaluation.
For what it is worth, if you explicitly type the result of your LEFT
function then you get the expected result:
SELECT ISNULL(
CAST(
LEFT(
'a big old string',
NULLIF(CHARINDEX('needle', 'haystack'), 0) - 1
)
AS VARCHAR(MAX))
, 'a big old string');
An additional point is that when you say you don't want to repeat any expressions (If 0 < CHARINDEX, then take CHARINDEX - 1, etc.), there are two things you should know, the first is that NULLIF(<expression>, <value>)
expands to a case expression - CASE WHEN <expression> = <value> THEN NULL ELSE <expression> END
, so is repeated, the second is that this doesn't matter, SQL Server can identify that this is the same expression used twice, and will evaluate it once and refer to the same result each time it is used.
using sql - Is not null in a select statement
You can use CASE
:
SELECT a. ....
(CASE WHEN a.Error1 IS NOT NULL
THEN ' - ' + a.Error1 + CHAR(13)+CHAR(10)
ELSE ''
END) +
(CASE WHEN a.Error2 IS NOT NULL
THEN ' - ' + a.Error2 + CHAR(13)+CHAR(10)
ELSE ''
END) +
(CASE WHEN a.Error3 IS NOT NULL
THEN ' - ' + a.Error3 + CHAR(13)+CHAR(10)
ELSE ''
END) +
...etc
IsNull() sql function
Remove Number
from second parameter of ISNULL
function.
Anything + NULL = NULL
so make the ISNULL
to result 0
when it is NULL
and then add 1
to the result
Update SomeTable set Number = IsNull(Number, 0) + 1 where
ItemCode = '000000' ;
or
Update SomeTable set Number = IsNull(Number+1, 1) where
ItemCode = '000000' ;
or two different updates (not recommended)
Update SomeTable set Number = Number + 1 where
ItemCode = '000000' AND Number IS NOT NULL;
Update SomeTable set Number = 1 where
ItemCode = '000000' AND Number IS NULL;
What is the PostgreSQL equivalent for ISNULL()
SELECT CASE WHEN field IS NULL THEN 'Empty' ELSE field END AS field_alias
Or more idiomatic:
SELECT coalesce(field, 'Empty') AS field_alias
Is there a concept which is the 'opposite' of SQL NULL?
No, there's no "universal acceptor" value in SQL that is equal to everything.
What you can do is raise the NVL into your comparison. Like if you're trying to do a JOIN:
SELECT ...
FROM my_table AS m
JOIN other_table AS o ON o.name = NVL(m.name, o.name)
So if m.name
is NULL, then the join will compare o.name
to o.name
, which is of course always true.
For other uses of NULL, you might have to use another technique that suits the situation.
Inverse of COALESCE
Here is a moderately unpleasant way of doing it:
set ansi_nulls off
if (null in (a, b, c, d, e) print 'got a null'
set ansi_nulls on
Related Topics
How to Count Most Consecutive Occurrences of a Value in a Column in SQL Server
Are SQL Queries Guaranteed to Execute Atomically When Using Union
Sql "If Exists..." Dynamic Query
Update Row When Matching Row Exists in Another Table
Display All Data of All Tables
How to Automatically Reset a Sequence's Value to 0 Every Year in Oracle 10G
All Operator Vs Any on an Empty Query
Delete Duplicate Records Using Rownum in Sql
Adding a Non-Nullable Column to Existing Table Fails. Is The "Value" Attribute Being Ignored
Performance of Querying Across Two MySQL Databases on The Same Server
Sql Server Table Locks in Long Query - Solution: Nolock
Extract Email Address from String Using Tsql
How to Add Months to a Current_Timestamp in Sql
How to Set a Default Value for One Column in SQL Based on Another Column
Call Dll Function from SQL Stored Procedure Using The Current Connection