Data not coming when old value is changed from null to other value - sql

Select statement is not displaying data when I change value from 0 to null or vice versa.
But when I change data from 0 to 1 select statement starts displaying data.
Please find my code (query)
declare #tmptable TABLE (Id INT, IsVal BIT)
INSERT Into #tmptable VALUES(1,0)
--SELECT * FROM #tmptable
DECLARE #Id INT
DECLARE #IsVal BIT
SET #Id=1
SET #IsVal=NULL
select #Id as PrimaryKeyValue
,CAST(IsVal as VARCHAR) as OldValue,CAST(ISNULL(#IsVal,'') as VARCHAR) as NewValue
,'IsVal' AS DisplayFieldName,
CASE IsVal
WHEN 1 THEN 'Yes'
WHEN 0 THEN 'No'
END as DisplayOldValue
,CASE #IsVal
WHEN 1 THEN 'Yes'
WHEN 0 THEN 'No'
END as DisplayNewValue
from #tmptable WHERE Id =#Id and ISNULL(IsVal,'')<>ISNULL(#IsVal,'')
There is problem with statement :-
ISNULL(IsVal,'')<>ISNULL(#IsVal,'')
Can't figure out the change I need to make to the above statement so that my query can work as I desired. Please help.
#IsVal variable is used to set value.
Thanks

You are correct, the problem is this expression: ISNULL(IsVal,'')<>ISNULL(#IsVal,'')
When IsVal is 0 and #IsVal is NULL, this becomes:
0 <> ''
which will compare as integers, so the '' becomes 0 and you get:
0 <> 0
So, in your case, 0, '' and NULL will all be treated as equal. You need to choose an invalid int (maybe -1?) or cast the 0 to a varchar to do that comparison.

Thanks for the help,
I was able to resolve the issue:-
declare #tmptable TABLE (Id INT, IsVal BIT)
INSERT Into #tmptable VALUES(1,0)
--SELECT * FROM #tmptable
DECLARE #Id INT
DECLARE #IsVal BIT
declare #oldval VARCHAR(10)
SET #Id=1
SET #IsVal=null
select #oldval=isval from #tmptable WHERE Id=1
print ISNULL(#oldval,'')
print ISNULL(#IsVal,'')
--if(ISNULL(CAST(#oldval AS INT),'')<>ISNULL(CAST(#IsVal AS INT),''))
--BEGIN
PRINT '1'
select #Id as PrimaryKeyValue
,CAST(IsVal as VARCHAR(10)) as OldValue,CAST(ISNULL(#IsVal,'') as VARCHAR(10)) as NewValue
,'IsVal' AS DisplayFieldName,
CASE IsVal
WHEN 1 THEN 'Yes'
WHEN 0 THEN 'No'
END as DisplayOldValue
,CASE #IsVal
WHEN 1 THEN 'Yes'
WHEN 0 THEN 'No'
END as DisplayNewValue
from #tmptable WHERE Id =#Id and ISNULL(CAST(IsVal AS VARCHAR),'null')<>ISNULL(CAST(#IsVal AS VARCHAR),'null')

Why not just use a simple comparison?
(IsVal = #IsVal or IsVal IS NULL AND #IsVal IS NULL)
You may still have problems with type conversion, assuming the types are not compatible.

Why not just use a simple comparison?
(IsVal = #IsVal or IsVal IS NULL AND #IsVal IS NULL)
You may still have problems with type conversion, assuming the types are not compatible.
If that is the case:
(IsVal = CONVERT(VARCHAR(255), #IsVal) or
IsVal IS NULL AND #IsVal IS NULL
)
There is no need to invent special values for isnull() or coalesce().

Related

Insert statement with a conditional target column

I am trying to store sensor data recorded to the appropriate target column, depending on what the latest settings are in the settings table (represented as #Unit in the code). The code I have so far gives me a syntax error at line 19 near 'Time', which I am not sure as to why. Any ideas?
CREATE PROCEDURE StoreTemp
#Temperature float,
#Seconds int,
#SessionId int,
#DatasetId int
AS
DECLARE
#Unit varchar(20),
#TempCol varchar(20)
SELECT #Unit = RecordingUnit from ReadLastUnit
SELECT #TempCol = (case #Unit when 'Celsius' then 'Temperature_C' else 'Temperature_F' END)
INSERT INTO DATASET (#TempCol, Time)
VALUES (#Temperature, GETDATE())
GO
You can't use a variable to specify a column name in an insert statement. The column name must be static.
You could use dynamic SQL, however in this case you can just conditionally insert a value into the correct column using a case expression as follows:
CREATE PROCEDURE StoreTemp
(
#Temperature float
, #Seconds int
, #SessionId int
, #DatasetId int
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Unit varchar(20), #TempCol varchar(20);
SELECT #Unit = RecordingUnit from ReadLastUnit;
--SELECT #TempCol = (case #Unit when 'Celsius' then 'Temperature_C' else 'Temperature_F' END);
INSERT INTO DATASET (Temperature_C, Temperature_F, [Time])
SELECT
CASE WHEN #Unit = 'Celsius' THEN #Temperature ELSE NULL END
, CASE WHEN #Unit != 'Celsius' THEN #Temperature ELSE NULL END
, GETDATE();
END
GO
For better performance and a neater query, you could even simplify the insert to do it all e.g.
INSERT INTO DATASET (Temperature_C, Temperature_F, [Time])
SELECT
CASE WHEN RecordingUnit = 'Celsius' THEN #Temperature ELSE NULL END
, CASE WHEN RecordingUnit != 'Celsius' THEN #Temperature ELSE NULL END
, GETDATE()
from ReadLastUnit;
Thats assuming you can always guarantee a single row in ReadLastUnit.

how to use declared variable to select data from another table in case when condition?

I made select query in which i want to select data based on condition.For this i declared one variable and set value of that variable in else part.I want to use that variable for further select in same else part how can i achieve this?Please Help
declare #stateid int
select CASE WHEN MstCustomerAddressInfo.StateId is null
THEN 24
ELSE set #stateid = MstCustomerAddressInfo.StateId
select mststate.statecode from mststate where MstState.StateId = #stateid
END AS StateCode
No, you can't have SET inside a CASE expression. Even you can't have multiple statements.
Same query you can write as following.
declare #stateid int
select CASE
WHEN MstCustomerAddressInfo.StateId is null THEN 24
ELSE
-- set #stateid = MstCustomerAddressInfo.StateId
(select mststate.statecode
from mststate
where MstState.StateId = MstCustomerAddressInfo.StateId)
END AS StateCode
from [Your_Table]

SQL Server 2014: How to cast a string value to int only if the value can be casted?

I try to cast a string value in a field of a table to int, but only in the case that the value stores a value that can be casted to int (in the other case the original value must be returned). Example:
DECLARE #ErrorCode nvarchar(1024)
SET #ErrorCode = 'a10'
SELECT IIF(TRY_CAST(#ErrorCode AS int) IS NULL, #ErrorCode, CAST(#ErrorCode AS int))
I've seen similar codes on StackOverflow.
My problem is that the SQL Server (2014) does not seem to short-circuit, and executes the cast always, even if TRY_CAST(#ErrorCode AS int) results in NULL. The result of the code above is the error "Conversion failed when converting the nvarchar value 'a10' to data type int."
See this sample on rextester.com
I also tried other variants with the same result:
SELECT CASE WHEN TRY_CAST(#ErrorCode AS int) IS NULL THEN #ErrorCode ELSE (SELECT CAST(#ErrorCode AS int)) END
SELECT CASE TRY_CAST(#ErrorCode AS int) WHEN 1 THEN CAST(#ErrorCode AS int) ELSE #ErrorCode END
How can I achieve my goal (avoid the cast in case the value in #ErrorCode cannot be casted)?
The simple solution would be to use COALSECE:
DECLARE #ErrorCode nvarchar(1024)
SET #ErrorCode = 'a10'
SELECT COALSECE(CAST(TRY_CAST(#ErrorCode AS int) as nvarchar(1024)), #ErrorCode)
However, I don't see the point of casting to int and then back to nvarchar.
To validate NULL you should IS NULL
DECLARE #ErrorCode NVARCHAR(1024)
SET #ErrorCode = 'a10'
SELECT IIF(TRY_CAST(#ErrorCode AS int) IS NULL, #ErrorCode, CAST(CAST(#ErrorCode AS int) AS VARCHAR(50)))
You need to convert the INT again to VARCHAR again to avoid the implicit conversion. IIF returns the data type with the highest precedence from the types in true_value and false_value.
The problem I see is trying to hold 2 different types in a single column. I'm not sure how you plan to use this information, but you could split the values in to numeric and text columns based on the type. You can do an ISNUMERIC() check and CAST to INT if it's true, otherwise leave it as text, like so:
CREATE TABLE #ErrorCodes ( ErrorCode NVARCHAR(10) )
INSERT INTO #ErrorCodes
( ErrorCode )
VALUES ( '123' ),
( 'a10' ),
( 'bbb' ),
( '456' )
SELECT ErrorCode AS OriginalVal ,
CASE WHEN ISNUMERIC(ErrorCode) = 1 THEN CAST(ErrorCode AS INT)
ELSE NULL
END AS NumericVal ,
CASE WHEN ISNUMERIC(ErrorCode) = 0 THEN ErrorCode
ELSE NULL
END AS NonNumericVal
FROM #ErrorCodes
DROP TABLE #ErrorCodes
Produces:
OriginalVal NumericVal NonNumericVal
=====================================
123 123 NULL
a10 NULL a10
bbb NULL bbb
456 456 NULL

SQL SERVER: Check if variable is null and then assign statement for Where Clause

I am trying to achieve something like the below in WHERE clause in sql.
if (#zipCode ==null)
begin
([Portal].[dbo].[Address].Position.Filter(#radiusBuff) = 1)
end
else if(#zipCode !=null)
begin
([Portal].[dbo].[Address].PostalCode=#zipCode )
end
I tried the following:
WHERE ((#zipCode IS NOT NULL AND ([Portal].[dbo].[Address].PostalCode=#zipCode)) OR (#zipCode IS NULL AND ([Portal].[dbo].[Address].Position.Filter(#radiusBuff) = 1)))
which is wrong. Can anyone help in framing the exact statement. Thanks!
is null is the syntax I use for such things, when COALESCE is of no help.
Try:
if (#zipCode is null)
begin
([Portal].[dbo].[Address].Position.Filter(#radiusBuff) = 1)
end
else
begin
([Portal].[dbo].[Address].PostalCode=#zipCode )
end
Isnull() syntax is built in for this kind of thing.
declare #Int int = null;
declare #Values table ( id int, def varchar(8) )
insert into #Values values (8, 'I am 8');
-- fails
select *
from #Values
where id = #Int
-- works fine
select *
from #Values
where id = isnull(#Int, 8);
For your example keep in mind you can change scope to be yet another where predicate off of a different variable for complex boolean logic. Only caveat is you need to cast it differently if you need to examine for a different data type. So if I add another row but wish to specify int of 8 AND also the reference of text similar to 'repeat' I can do that with a reference again back to the 'isnull' of the first variable yet return an entirely different result data type for a different reference to a different field.
declare #Int int = null;
declare #Values table ( id int, def varchar(16) )
insert into #Values values (8, 'I am 8'), (8, 'I am 8 repeat');
select *
from #Values
where id = isnull(#Int, 8)
and def like isnull(cast(#Int as varchar), '%repeat%')
is null can be used to check whether null data is coming from a query as in following example:
declare #Mem varchar(20),#flag int
select #mem=MemberClub from [dbo].[UserMaster] where UserID=#uid
if(#Mem is null)
begin
set #flag= 0;
end
else
begin
set #flag=1;
end
return #flag;
Try a case statement
WHERE
CASE WHEN #zipCode IS NULL THEN 1
ELSE #zipCode
END
Try the following:
if ((select VisitCount from PageImage where PID=#pid and PageNumber=5) is NULL)
begin
update PageImage
set VisitCount=1
where PID=#pid and PageNumber=#pageno
end
else
begin
update PageImage
set VisitCount=VisitCount+1
where PID=#pid and PageNumber=#pageno
end

How to Compare two strings using a if in a stored procedure in sql server 2008?

I want to do something like this:
declare #temp as varchar
set #temp='Measure'
if(#temp == 'Measure')
Select Measure from Measuretable
else
Select OtherMeasure from Measuretable
Two things:
Only need one (1) equals sign to evaluate
You need to specify a length on the VARCHAR - the default is a single character.
Use:
DECLARE #temp VARCHAR(10)
SET #temp = 'm'
IF #temp = 'm'
SELECT 'yes'
ELSE
SELECT 'no'
VARCHAR(10) means the VARCHAR will accommodate up to 10 characters. More examples of the behavior -
DECLARE #temp VARCHAR
SET #temp = 'm'
IF #temp = 'm'
SELECT 'yes'
ELSE
SELECT 'no'
...will return "yes"
DECLARE #temp VARCHAR
SET #temp = 'mtest'
IF #temp = 'm'
SELECT 'yes'
ELSE
SELECT 'no'
...will return "no".
You can also try this for match string.
DECLARE #temp1 VARCHAR(1000)
SET #temp1 = '<li>Error in connecting server.</li>'
DECLARE #temp2 VARCHAR(1000)
SET #temp2 = '<li>Error in connecting server. connection timeout.</li>'
IF #temp1 like '%Error in connecting server.%' OR #temp1 like '%Error in connecting server. connection timeout.%'
SELECT 'yes'
ELSE
SELECT 'no'
declare #temp as varchar
set #temp='Measure'
if(#temp = 'Measure')
Select Measure from Measuretable
else
Select OtherMeasure from Measuretable
What you want is a SQL case statement.
The form of these is either:
select case [expression or column]
when [value] then [result]
when [value2] then [result2]
else [value3] end
or:
select case
when [expression or column] = [value] then [result]
when [expression or column] = [value2] then [result2]
else [value3] end
In your example you are after:
declare #temp as varchar(100)
set #temp='Measure'
select case #temp
when 'Measure' then Measure
else OtherMeasure end
from Measuretable