how to treat varchar zero-length as null in SQL Server? - sql-server

I know in SQL Server, a zero-length string ('') is different from null, but is there any way to determine whether it is a zero-length string or null?
The business requirement is:
If user input an index word, let's say IN_DATE, then match the IN_DATE;
If user input nothing for IN_DATE, then match every thing
I tested by using following statements.
DECLARE #IN_DATE VARCHAR(8)
SET #IN_DATE = null
--SET #IN_DATE = ''
SELECT
CONVERT(VARCHAR(8), ISNULL(#IN_DATE, GETDATE()), 112) AS OUT_DATE
Neither null nor zero-length VARCHAR will bring me the expected result. But I tried the following query which works correctly.
SELECT
CONVERT(VARCHAR(8), ISNULL(NULL, GETDATE()), 112) AS OUT_DATE
Anyone can tell me what's the internal logic of these queries? Thanks so much.

DECLARE #PASSED AS VARCHAR(50) = NULL
SELECT
CASE
WHEN ISDATE(#PASSED) = 0 THEN GETDATE()
ELSE CONVERT(DATE, #PASSED)
END AS DATE_OUT
1) If NULL is used for passed then today's date is returned
2) If text '13/13/2014' is passed but not a valid date then again today's date is passed
3) If a valid date '03/13/2014' is passed it is converted into a valid date type

To default to today if the variable is NULL or empty;
SELECT ISNULL(NULLIF(#IN_DATE, ''), GETDATE())
For (2) If user input nothing for IN_DATE, then match every thing
WHERE
(NULLIF(#IN_DATE, '') IS NULL OR SomeField = #IN_DATE)

DECLARE #IN_DATE VARCHAR(8) = ''
SELECT
(CASE #IN_DATE WHEN ''
THEN CONVERT(VARCHAR(100), GETDATE(), 112)
ELSE #IN_DATE END) AS OUT_DATE

Related

Conversion failed when converting date and/or time from character string- Not sure why?

My date Format is "MMddyy" in sql .. When am trying to do as below it through me the date conversion error but am not sure what I need to do there??
Condition Failing: My WarrantReceivedDate should be less than startDate
and DateWarrantExecuted should be >= StartDate ?
Any Help? Thanks in Advance
declare #startDate VARCHAR(6) = '010119'
declare #endDate VARCHAR(6) = '013119'
DECLARE #MyTable TABLE (
WarrantIssuingAuthority varchar(100),
CountType varchar(100),
CountRecords int
)
insert into #MyTable (WarrantIssuingAuthority, CountType, CountRecords)
select WarrantIssuingAuthority, 'WARRANTS BEGINNING OF MONTH', count(*)
from [PM].WarrantInformation
where TypeOfWarrantIssued!='COM'
and HowExecuted!='R' and HowExecuted!='U'
and DeletedIndicator!='D'
and DeletedIndicator!='P'
and CONVERT(VARCHAR(10), CAST((RIGHT(WarrantReceivedDate,2) + LEFT(WarrantReceivedDate,4)) AS DATE),112) < CONVERT(VARCHAR(10), CAST((RIGHT(#startDate,2) + LEFT(#startDate,4)) AS DATE),112)
and (DateWarrantExecuted='' or (CONVERT(VARCHAR(10), CAST((RIGHT(DateWarrantExecuted,2) + LEFT(DateWarrantExecuted,4)) AS DATE),112) >= CONVERT(VARCHAR(10), CAST((RIGHT(#startDate,2) + LEFT(#startDate,4)) AS DATE),112)))
group by WarrantIssuingAuthority
select * from #MyTable order by WarrantIssuingAuthority
We can't see the definition of your table or the data contained within but its possible that there is a value there that can't be properly converted to a date. For example, maybe there is a value 093118 which is a valid varchar value, but not a valid date.

Convert VARCHAR in format YYMMDD to YYYYMMDD and ignore invalid date formats

I have a table with a VARCHAR field called ArrivalDate in format yymmdd (such as 170202).
I am writing a query which converts it to yyyymmdd so it should become 20170202.
However my problem is that I need to cater for the case when inappropriate data is entered into the field, and my query needs to exclude that data. I am achieving this exclusion by using the ISDATE function of TSQL. I also need to select the least recent entry (I'm using order by asc for this).
I am using a variety of converts to write this query, below is my implementation with a sample table and data.
Declare #tmp TABLE (theDates VARCHAR(MAX))
INSERT INTO #tmp VALUES('170202')
SELECT TOP 1 t.theDates
WHEN (ISDATE(t.theDates) = 1) THEN CONVERT( VARCHAR(max),CONVERT(datetime t.theDates), 112)
FROM #tmp t
WHERE (ISDATE(t.theDates) = 1)
ORDER BY CAST(t.theDates as DATE)
However I do not like my approach and it occasionally fails conversion and throws an error with values such as 02/02/02 which breaks the query. Can someone please show me a better way of writing this functionality.
Much appreciated!
You can use TRY_CONVERT and CONVERT to get the correct format and convert the value. Then check that the string is exactly 6 character to prevent other formats from being returned.
SELECT
convert(char(10),convert(date, theDates, 12),112)
FROM
(values('02/02/02'),('170202')) x(theDates)
WHERE
try_convert(date, theDates, 12) is not null
and len(theDates) = 6
You can use cast(#date as datetime)
declare #date varchar(max);
set #date='170202';
select
CASE WHEN (ISDATE(cast(#date as datetime)) = 1)
THEN CONVERT(VARCHAR(max), CONVERT(datetime, cast(#date as datetime)), 112) end
from table
set #date='02/02/02';
select
CASE WHEN (ISDATE(cast(#date as datetime)) = 1)
THEN CONVERT(VARCHAR(max), CONVERT(datetime, cast(#date as datetime)), 112) end
from table
please use create function for check dateformat is Valid or not and use this fun in your query inside cash clouse.
ALTER FUNCTION dbo.f_CheckDate
(#InDate nvarchar(25))
RETURNS DATE
AS
BEGIN
declare #Return DATETIME
select #return = CASE WHEN ISDATE(#InDate) = 1
THEN #InDate
ELSE NULL
END
return #return
END
You could use TRY_CAST or TRY_CONVERT if value cannot be cast it will return NULL.
SELECT
TRY_CAST('20170228' AS DATETIME),
TRY_CAST('170228' AS DATETIME),
TRY_CONVERT(DATETIME, '20170228'),
TRY_CONVERT(DATETIME, '170228')
This works for SQL Server 2012 and newer.

SQL Server : converting Null date times

I have a query in SSMS which is returning 1900-01-01, how can I use a CASE WHEN accurately to replace 1900-01-01 with '' (a blank not a null).
CAST(ISNULL(CAST(CONVERT(DATE, cmmt.[CmmtExpirationDate], 101) AS NVARCHAR(20)), '') AS DATE) AS [Cmmt Expiration Date]
Result: 1900-01-01
I tried this but no luck (terrible syntax):
CASE
WHEN (CAST(ISNULL(cast(convert(Date, cmmt.[CmmtExpirationDate] , 101) as nvarchar(20)), '') = '1900-01-01')
THEN ''
ELSE CAST(ISNULL(cast(convert(Date, cmmt.[CmmtExpirationDate] , 101) as nvarchar(20)),'') AS DATE
END
The result of your expression needs to have a fixed data type. DATE is not possible, since '' is not a valid date. nvarchar(20) would be an option, but that means that your result will be a string even if it is not 1900-01-01.
Once you accept that, the solution is simple:
CASE WHEN cmmt.[CmmtExpirationDate] = '1900-01-01'
THEN CONVERT(nvarchar(20), cmmt.[CmmtExpirationDate])
ELSE CONVERT(nvarchar(20), '')
END
You might want to specify the desired output format as a third parameter to the first CONVERT statement.
(I assume that CmmtExpirationDate is of type DATE, because if it isn't, it should have been mentioned in the question.)
You can use try_convert as below:
try_convert(date, case when datecolumn='' then null else datecolumn end)

Change NULL values in Datetime format to empty string

I have a table which contains 'NULL' values which are of type 'Datetime'. Now i have to convert those into empty string but when when i use convert function
ISNULL( [Accrued Out of Default] ,'' )
here accrued into default is of datetime type, what it does it changes null to '1900-01-01 00:00:00.000' instead of empty
Then i try to convert them into varchar and apply same
ISNULL(CONVERT(varchar(50), [Amort Into Default] ),'')
Now I am able to convert into empty string but now those datetime are converted to string which I needed in datetime
So I try to CAST, CONVERT but non of them works.
CONVERT(Datetime,'ISNULL(CONVERT(varchar(50), [Amort Into Default] ),'')',120)
This gives error.
Is there any possible solution to this.
> **Solution Hi someone answered this to do as.
> ISNULL(CONVERT(varchar(50), [Amort Into Default] ,120),'') and it works I dont know why .
**
CASE and CAST should work:
CASE WHEN mycol IS NULL THEN '' ELSE CONVERT(varchar(50), mycol, 121) END
using an ISNULL is the best way I found of getting round the NULL in dates :
ISNULL(CASE WHEN CONVERT(DATE, YOURDate) = '1900-01-01' THEN '' ELSE CONVERT(CHAR(10), YOURDate, 103) END, '') AS [YOUR Date]
declare #date datetime; set #date = null
--declare #date datetime; set #date = '2015-01-01'
select coalesce( convert( varchar(10), #date, 103 ), '')
I had something similar, and here's (an edited) version of what I ended up using successfully:
ISNULL(CONVERT(VARCHAR(50),[column name goes here],[date style goes here] ),'')
Here's why this works: If you select a date which is NULL, it will show return NULL, though it is really stored as 01/01/1900. This is why an ISNULL on the date field, while you're working with any date data type will not treat this as a NULL, as it is technically not being stored as a NULL.
However, once you convert it to a new datatype, it will convert it as a NULL, and at that point, you're ISNULL will work as you expect it to work.
I hope this works out for you as well!
~Eli
Update, nearly one year later:
I had a similar situation, where I needed the output to be of the date data-type, and my aforementioned solution didn't work (it only works if you need it displayed as a date, not be of the date data type.
If you need it to be of the date data-type, there is a way around it, and this is to nest a REPLACE within an ISNULL, the following worked for me:
Select
ISNULL(
REPLACE(
[DATE COLUMN NAME],
'1900-01-01',
''
),
'') AS [MeaningfulAlias]
This also works:
REPLACE(ISNULL(CONVERT(DATE, #date), ''), '1900-01-01', '') AS 'Your Date Field'
select case when IsNull(CONVERT(DATE, StartDate),'')='' then 'NA' else Convert(varchar(10),StartDate,121) end from table1
Select isnull(date_column_name,cast('1900-01-01' as DATE)) from table name
declare #mydatetime datetime
set #mydatetime = GETDATE() -- comment out for null value
--set #mydatetime = GETDATE()
select
case when #mydatetime IS NULL THEN ''
else convert(varchar(20),#mydatetime,120)
end as converted_date
In this query, I worked out the result came from current date of the day.
You could try the following
select
case when mydatetime IS NULL THEN ''
else convert(varchar(20),#mydatetime,120)
end as converted_date
from sometable
-- Testing it out could do --
declare #mydatetime datetime
set #mydatetime = GETDATE() -- comment out for null value
--set #mydatetime = GETDATE()
select
case when #mydatetime IS NULL THEN ''
else convert(varchar(20),#mydatetime,120)
end as converted_date
Hope this helps!
Try to use the function DECODE
Ex: Decode(MYDATE, NULL, ' ', MYDATE)
If date is NULL then display ' ' (BLANK) else display the date.

How to solve the date comparison issue in SQL Server?

I am using the following way to compare two dates:
if CONVERT(varchar(20), #ScheduleDate, 101) >= CONVERT(varchar(20), #CurrentDateTime, 101)
This is working fine for the current year, but when the comes in yearly like one date is 12/31/2012 and 1/1/2013 then its not working.
Please help me how can I resolve this.
why do you comparing strings?
you can compare dates
if #ScheduleDate >= #CurrentDateTime
but if your date contains time, I usually do
if convert(nvarchar(8), #ScheduleDate, 112) >= convert(nvarchar(8), #CurrentDateTime, 112)
112 datetime format is YYYYMMDD so it's good for compare dates
You have to remember that string comparison is from left to right, so "1/...." is smaller than "12/...".
You need to use DATETIME comparisons, not string comparison.
Something like
DECLARE #ScheduleDate DATETIME = '1/1/2013',
#CurrentDateTime DATETIME = '12/31/2012'
IF (#ScheduleDate >= #CurrentDateTime)
BEGIN
SELECT #ScheduleDate, #CurrentDateTime
END
DECLARE #ScheduleDateString VARCHAR(20) = '1/1/2013',
#CurrentDateTimeString VARCHAR(20) = '12/31/2012'
IF (CONVERT(DATETIME,#ScheduleDateString,101)>=CONVERT(DATETIME,#CurrentDateTimeString,101))
BEGIN
SELECT CONVERT(DATETIME,#ScheduleDateString,101),CONVERT(DATETIME,#CurrentDateTimeString,101)
END
SQL Fiddle DEMO
Note that if the variables are already datetimes, you do not need to convert them.
Assuming that both variables are currently DateTime variables, can't you just compare them without converting to strings?
declare #ScheduleDate DATETIME, #CurrentDateTime DATETIME
SET #ScheduleDate = '1 Jan 2013'
SET #CurrentDateTime = GetDate()
IF (#ScheduleDate >= #CurrentDateTime)
BEGIN
SELECT 'Do Something'
END
ELSE
BEGIN
SELECT 'Do Something Else'
END
when you use CONVERT(nvarchar(8), #ScheduleDate, 112) function it's return string instead of date.
so,
Use "112" DateFormat in Sql Server it's return string in "YMD" format without any sepration.
compare that string in your query and get desire output.
Such as "if CONVERT(nvarchar(8), #ScheduleDate, 112) >= CONVERT(nvarchar(8), #CurrentDateTime, 112)"
I would not use CONVERT to compare formatted strings. It is slow (well, more like microseconds, but still)
I use a UDF for SQL prior to version 2008
CREATE FUNCTION [dbo].[DateOnly] (#Date DateTime)
RETURNS Datetime AS
BEGIN
Return cast (floor (cast (#Date as float)) as DateTime)
END
and for versions >=2008 this approach
select convert(#MyDateTime as DATE)
Of course, you can compare datetime values directly, but to know whether two datetime values are on the same date (ignoring the time component), the above versions have proven to be effectivy.
Date : From and To with following format
from_Date# = #dateformat("#form.from#", "mm/dd/yyyy")
to_Date# = #dateformat("#now()#" + 1, "mm/dd/yyyy")
In SQL Statement
WHERE a.DateCreated >= CAST ('#from_date#' AS DATE) and a.DateCreated <= CAST('#to_date#' AS DATE)
This is working fine without any cast of original date time column

Resources