Conversion failed when converting date and/or time from character string - sql-server

I wrote a procedure which actually searches a record.
when i execute it, it gives an error which says:
Conversion failed when converting date and/or time from character string.
Statement:
((CONVERT(varchar, DATEPART(YYYY, Tbl_Contract.ContractDate), 101)) = #Year or #Year = '')

It appears that you are converting the date to a year value :
DATEPART(YYYY,#ContractDate)
and then trying to convert that back to a date :
CONVERT(varchar, DATEPART(YYYY, #ContractDate),101)
You might try this : EDIT
datepart(yyyy, CONVERT(datetime, #ContractDate))

Since ContractDate is a Varchar you can either parse directly with
SubString(ContractDate, x, 4) = #YearString
or you can encapsulate the condition
Case when IsDate(ContractDate) = 1
then ((CONVERT(varchar, DATEPART(YYYY, #a), 101)))
else NULL
end

Related

Adding fixed time onto datetime gives unexpected results

I have a query that takes two datetime variables (Start date and end date) and appends two differing fixed times to allow for a business trading time offset.
An example of a test query using this logic is:
DECLARE #startdate datetime;
DECLARE #enddate datetime;
SET #startdate = convert(datetime,'2017-01-01')
SET #enddate = convert(datetime,'2017-01-02')
SELECT *
FROM ig_Business..Check_Item_Detail CID (NOLOCK)
JOIN ig_business..Check_Sales_Detail CSD (NOLOCK) ON CSD.transaction_data_id = CID.transaction_data_id
WHERE csd.tendered_date_time BETWEEN DATEADD(m, DATEDIFF(m, 0, convert(date, #STARTDATE)), 0) + '06:00:00'
AND DATEADD(m, DATEDIFF(m, 0, convert(date, #ENDDATE)), 0) + '05:59:59'
However, the result set for this query is empty, and I am unsure why, because when I run
select DATEADD(m, DATEDIFF(m, 0, convert(date, #STARTDATE)), 0) + '06:00:00'
i get back a seemingly valid datetime : 2017-01-01 06:00:00.000
An example of what is returned when I remove the time restriction:
i get back a seemingly valid datetime : 2017-01-01 06:00:00.000
You're not.
You're getting back a date that has been automatically cast to a string, and have glued another string on the end, giving you a string that looks like a datetime.
If you want to add something to the date, use another dateadd(). This will give you a BETWEEN comparison with actual datetimes.
Right now you are doing a "between" with a datetime and a string.
I'm surprised it doesn't throw an error.
If 2012+, you can use format() to append a time to a date/datetime value
Example
Declare #startdate date = '2017-01-01'
Select format(#startdate,'yyyy-MM-dd 06:00:00')
Returns
2017-01-01 06:00:00
This format() can be included in your where
...
Where SomeDateTime between format(#startdate,'yyyy-MM-dd 06:00:00')
and format(#enddate,'yyyy-MM-dd 17:00:00')

TSQL Next Payment Date February

My function works throughout the year, to respond with the next payment date of the month for a scheduled transaction. When spanning over to next year however, it fails with "Conversion failed when converting date and/or time from character string."
The first date is the start of a chosen month. The second date is the due date of a transaction, an entry from a list of many transactions with dates. It works all year until I get past the end of the year.
How would I fix this to respond with the correct date?
SELECT dbo.NextPaymentDate('2/1/2017', '1/30/2017')
returns 2/28/2017
SELECT dbo.NextPaymentDate('2/1/2017', '12/30/2016')
returns
Conversion failed when converting date and/or time from character string
Code:
--SELECT dbo.NextPaymentDate('2/1/2017','12/30/2016')
ALTER FUNCTION [dbo].[NextPaymentDate]
(#RegisterDate DATE, #PaymentDueDate DATE)
RETURNS DATE
AS
BEGIN
DECLARE #returnDate DATE, #MonthDiff int
SET #MonthDiff = MONTH(#RegisterDate) - MONTH(#PaymentDueDate)
SELECT #returnDate =
CAST(CONVERT(varchar, YEAR(#RegisterDate)) + '-'
+ CONVERT(varchar, MONTH(#RegisterDate)) + '-'
+ CONVERT(varchar, DAY(DATEADD(mm, #MonthDiff, #PaymentDueDate))) AS DATE)
RETURN #returnDate
END
Seems the issue was with the #MonthDiff, it was returning a negative value and the casting was creating a double negative, literally, --, with the datepart separators
I changed to this, and ran a few tests and seems to work for many date variations
SET #MonthDiff = ABS(DATEDIFF(MONTH, #RegisterDate, #PaymentDueDate))

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)

How to convert int year into valid date format in my stored procedure

My stored proc has the following select statement:
select Name,Holiday from tblNames where ID = #ID and DATENAME(YEAR, GETDATE()) = #Year
When executing the statement I have an error
"Error converting data type int to nvarchar."
How can I convert #Year parameter to a correct year?
The return type of the datename function is nvarchar, you want the datepart function that returns an integer value, so change to DATEPART(YEAR, GETDATE()) instead.
datename is what you would use to get the name of a month or weekday.
Or you could use the year(getdate()) function instead as Gordon L mentioned in a comment.
I'd recommend to switch back from fixing specific error message to the original question. You have a date in your table and need to filter it by range. So just provide to server the range bounds. This will also avoid any conversions of stored data. To avoid tail time issue you may append '23:59:59.997' to the upper bound of range or (my advice) provide next date and compare by < instead of <=
set #startdate = ...
set #enddate = dateadd(dd, 1, ...)
select *
from mytable
where t.date >= #startdate and t.date < #enddate
Complicated conversions can make it impossible to use appropriate index. If you can convert your arguments and provide prepared values to server - strive to do so.

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