How to know if my variable datetime is null? - sql

I'm trying to compare if my variable datetime is NULL, but it doesn't work, I'm new making comparising in SQL, so could someone said me how is the good way. This is my code:
declare #FechaInicial datetime
set #FechaInicial = (select FecharIncialDescarga
from Contenedores where Id_Contenedor=#IdContenedor)
if(#FechaInicial = NULL) ---
begin
end

The direct answer to your question is is null:
if (#FechaInicial IS NULL)
This is because almost any comparison to NULL returns NULL, and NULL is treated as false.
However, I want to point out that you might really intend this logic:
if (not exists (select 1 from Contenedores where Id_Contenedor = #IdContenedor))
begin
. . .
end;
Although there is nothing wrong with assigning the value to a variable and checking for NULL, this is clearer and can be more efficient.

You can try this with if(#FechaInicial IS NULL) as below.
declare #FechaInicial datetime
set #FechaInicial = (select FecharIncialDescarga from Contenedores
where Id_Contenedor=#IdContenedor)
if(#FechaInicial IS NULL) ---
begin
end
If you want to check NULL and also empty, you can try if(ISNULL(#FechaInicial, '') = '') as below.
declare #FechaInicial datetime
set #FechaInicial = (select FecharIncialDescarga
from Contenedores where Id_Contenedor=#IdContenedor)
if(ISNULL(#FechaInicial, '') = '') ---
begin
end
Also a recommendation, Instead of a SET used above, you can refactor it as below with a SELECT
SELECT #FechaInicial = FecharIncialDescarga
FROM Contenedores WHERE Id_Contenedor = #IdContenedor

Related

i cant update to datetime table

i have already have date value
SET #LogDate1 = CAST(#logtanggal AS datetime)
SET #LogDate = CONVERT(varchar, #LogDate1, 20 )
#logtanggal is varchar, and i already convert it to datetime, the problem is when i try to update value of #logdate to the table, there are error mssg like
Msg 241, Level 16, State 1, Procedure LockAmountOnline_t24_Active, Line 108
Conversion failed when converting date and/or time from character string.
the table data type is already datetime, why i cant update to table?
the update query
SET #sql1 = 'UPDATE Lock_Amount_Trx
SET
GenerateDate = GETDATE(), -- datetime
LogDate ='''+#Logdate1+''', -- datetime
LogStatus = CASE WHEN tlat.logdescription = ''SUCCESS.UPD'' THEN ''SUCCESS''
WHEN tlat.logdescription = ''NOT.UPD-KTA'' THEN ''NOT CHANGED''
END ,
LogDescription = tlat.logdescription -- varchar
FROM ##TempLockAmmountTrx tlat, Lock_Amount_Trx lat
WHERE tlat.cuscode = lat.Custcode AND tlat.norekdeb = lat.NoRekDebet AND tlat.lockammount = lat.TotalLockAmount AND lat.Id ='''+ #idFile +''''
EXEC (#sql1)
converted varchar(top) and target table date format date (bottom)
There is literally no need for "dynamic" SQL here, there's nothing dynamic in your code. All you are doing here is creating a huge security flaw in your code. SQL injection is not a good thing, and you should never write code that can suffer from it.
Stop using dynamic SQL and the error doesn't happen:
UPDATE Lock_Amount_Trx
SET GenerateDate = GETDATE(), -- datetime
LogDate = #Logdate1, -- datetime
LogStatus = CASE WHEN tlat.logdescription = 'SUCCESS.UPD' THEN 'SUCCESS'
WHEN tlat.logdescription = 'NOT.UPD-KTA' THEN 'NOT CHANGED'
END,
LogDescription = tlat.logdescription -- varchar
FROM ##TempLockAmmountTrx tlat, Lock_Amount_Trx lat
WHERE tlat.cuscode = lat.Custcode
AND tlat.norekdeb = lat.NoRekDebet
AND tlat.lockammount = lat.TotalLockAmount
AND lat.Id = #idFile;
If you do ever need to actually use dynamic SQL, I suggest reading up on some of the basics, such as properly quoting your dynamic objects (which the above has none), and parametrising your statements. Rather than putting this all in the answer (which, considering that you don't need dynamic SQL, means it's not really really), you can read about this in my article Dos and Don'ts of Dynamic SQL.
Also, be very careful with your expression CONVERT(varchar, #LogDate1, 20 ). Always declare your length, scale and precissions when using data types.
You need to use parameterized Dynamic SQL :
SET #sql1 = 'UPDATE Lock_Amount_Trx
SET
GenerateDate = GETDATE(), -- datetime
LogDate = #LogDate1, -- datetime
LogStatus = CASE WHEN tlat.logdescription = ''SUCCESS.UPD'' THEN ''SUCCESS''
WHEN tlat.logdescription = ''NOT.UPD-KTA'' THEN ''NOT CHANGED''
END ,
LogDescription = tlat.logdescription -- varchar
FROM ##TempLockAmmountTrx tlat, Lock_Amount_Trx lat
WHERE tlat.cuscode = lat.Custcode AND tlat.norekdeb = lat.NoRekDebet AND tlat.lockammount = lat.TotalLockAmount AND lat.Id = #idFile'
exec sp_executesql #sql1, N'#LogDate1 DATETIME, #idFile varchar(255)', #LogDate1, #idFile
Note : I don't know what is the type of idfile so, change the type accordingly.
EDIT : As larnu pointed out that this query will not require any Dynamic SQL.
So, you can use plain update statement.

Refactoring a COALESCE comparison

In the OR section of a WHERE clause I have something like this:
COALESCE(Table2.FireDate, Table1.HireDate,'06/06/2079') = ISNULL(Table3.DeathDate,'06/06/2079')
I wanted to see is there a way to avoid COALESCE call and still achieve the same result? My hope is gaining some performance if possible.
I don't sure that performance will be better. But you can get rid from coalesce as you want:
declare #fireDate date = null -- '01/20/2017'
declare #hireDate date = '01/20/2017'
declare #deathDate date = '01/20/2017'
if (COALESCE(#fireDate, #hireDate, '06/06/2079') = ISNULL(#deathDate, '06/06/2079'))
begin
select '+'
end;
if(#fireDate is null and #hireDate is null and #deathDate is null)
or (#fireDate = #deathDate)
or (#fireDate is null and #hireDate = #deathDate) begin
select '+'
end;

How to set optional parameter for int type variable

Have two variable StatusTypeTestID and StatusTestID want to set them as optional in where clause as like bellow,but optional option not work for int variable.
Note: default value for int variable is 0
DECLARE #StatusTypeTestID as int
SET #StatusTypeTestID = 1
DECLARE #StatusTestID as int
SET #StatusTestID = 0
select *
from LiveCustomerStatus
where (StatusType=#StatusTypeTestID
and (Status = #StatusTestID or #StatusTestID is null))
As you were already trying, you can check if your parameters have been set as null or if they match the correspondent field.
This way you can leave a parameter as null if you want it to be optional, not affecting the result.
select *
from LiveCustomerStatus
where (#StatusTypeTestID is null or StatusType=#StatusTypeTestID)
and (#StatusTestID is null or Status = #StatusTestID)
option(recompile)
I have added a option(recompile) clause that will force SQL Server to recompile the query at every execution. This way it will use the appropriate indexes to optimize it depending of the value of the parameters (wether they are null or not).
You can comment both set statements and below query will work:
select * from LiveCustomerStatus
where (#StatusTypeTestID is null or StatusType=#StatusTypeTestID)
and (#StatusTestID is null or Status = #StatusTestID)
Use CASE Statement in WHERE clause :
SELECT *
FROM LiveCustomerStatus
WHERE StatusType = CASE WHEN ISNULL(#StatusTypeTestID,'') = '' THEN
StatusType ELSE #StatusTypeTestID END
AND Status = CASE WHEN ISNULL(#StatusTestID,'')= '' THEN Status ELSE
#StatusTestID END

Conversion from nvarchar to float isn't working

I am unable to get the following query to work due to errors upon conversion from nvarchar to float; I need to convert theData field to float in order to round it, but the data is originally an NVARCHAR(20) because the column holds character data as well. I've tried casting each of the instances of theData to float but it still didn't work, can anyone tell me what I'm missing?
UPDATE tblData SET tblData.theNumericData = CASE WHEN IsNumeric([theData]) = 1
THEN Round(Convert(float, [theData]),(Len([theData])-Charindex('.',[theData])))
ELSE Null END
WHERE tblData.theFlag =1;
I have tried the following two variants...
UPDATE tblData SET tblData.theNumericData = CASE WHEN IsNumeric([theData]) = 1
THEN Round(Convert(float, [theData]),(Len(Convert(float, [theData]))-
Charindex('.',Convert(float, [theData]))))
ELSE Null END
WHERE tblData.theFlag =1;
and...
UPDATE tblData SET tblData.theNumericData = CASE WHEN IsNumeric([theData]) = 1
THEN Convert(nvarchar(20),Round(Convert(float, [theData]),(Len(Convert(float,
[theData]))- Charindex('.',Convert(float, [theData]))))) ELSE Null END
WHERE tblData.theFlag =1;
Can't answer the question because we don't know the error you're getting but... you should move the case to where... it'll make it more readable.
UPDATE tblData
SET tblData.theNumericData = Convert(float, [theData])
WHERE IsNumeric([theData]) = 1 AND tblData.theFlag =1;

SQL multiple if statements, same result set, different argument

I am writing a stored proc that calculates a WHOLE bunch of different things, but I have a bit in it, that is repeated about 9 times.
eg:
if #argA = 1 (true)
select Count(samples) from dbo.X where type = #argAType
if #argB = 1 (true)
select Count(samples) from dbo.X where type = #argBType
if #argC = 1
select Count(samples) from dbo.X where type = #argCType
and so on...
how can I write a function (or something similar) that I can pass in a bit (true or false), and other argument, and only return the result set if true???
Is this what you're looking for? This is the best I can deduce based on the question as it's currently posted.
SELECT COUNT(samples)
FROM dbo.X
WHERE
(type=#argAType AND #argA=1)
OR
(type=#argBType AND #argB=1)
OR
(type=#argCType AND #argC=1)
In function form, I think this is right:
CREATE FUNCTION GetCount(#n AS BIGINT) RETURNS BIGINT
AS
BEGIN
DECLARE #count BIGINT
SELECT #count = COUNT(samples)
FROM dbo.X
WHERE
(type=#argAType AND #argA=1)
OR
(type=#argBType AND #argB=1)
OR
(type=#argCType AND #argC=1)
RETURN #count
END