Error converting data type varchar to numeric when using datediff - sql

I am trying to calculate a date using two table. Here the query
select DATEDIFF(DAY, convert(varchar,D.BUSS_DATE, 23), convert(varchar,A.BUSS_DATE,23))
FROM dbo.TrxA1 A WITH (NOLOCK)
LEFT JOIN SOURCE_TBL_MASTER_EXCHANGE_RATE_HISTORY D WITH (NOLOCK)
ON A.CCY = D.SPOT_RATE
But I get the error
Error converting data type varchar to numeric.
I have been converting those date columns to varchar but the error is still same.
Please help. Thank you.

You should be converting to dates not strings. No conversion may be needed at all if your data is using the correct types:
select datediff(day, D.BUSS_DATE, A.BUSS_DATE)
from dbo.TrxA1 A left join
SOURCE_TBL_MASTER_EXCHANGE_RATE_HISTORY D
on A.CCY = D.SPOT_RATE;
If your values are inappropriate stored as strings, you can convert using:
select datediff(day, convert(date, D.BUSS_DATE, 23), convert(date, A.BUSS_DATE, 23))
If you still have a problem, you can fix it using try_convert():
select datediff(day, try_convert(date, D.BUSS_DATE, 23), try_convert(date, A.BUSS_DATE, 23))
But that just masks the problem. You should find the offensive values:
select buss_date
from dbo.TrxA1 A
where try_convert(date, buss_date, 23) is null and buss_date is not null;
Then fix the values and change the data type to an appropriate date/time type.
Finally, do not use NOLOCK unless you know what it is doing. And you probably don't. NOLOCK is a license that says: "You can get me data from the table that is not 100% accurate."

Related

Conversion from INT to varchar in sql

I have a table where there are values like 20170730 and also 0 values are there which is INT type
I am trying to convert it to value like 30/07/2017, for which i am using the below code,
Select convert(NVARCHAR(10),convert(date,convert(NCHAR(8),datecolumn)),103) from table
But for the zero values i am getting the below error
Conversion failed when converting date and/or time from character string.
If i delete all the zero this working fine but problem having with zero.
My requirement is to convert when there a date value and if 0 are there then it should be zero only like below,
Result
30/07/2017
0
Can u pls help
As already pointed out in the comments, you can try to use a CASE expression
SELECT CASE
WHEN nmuloc = 0 THEN
'0'
ELSE
convert(varchar(10),
convert(date,
convert(varchar(8),
nmuloc),
112),
103)
END
FROM elbat;
or try_convert() and coalesce().
SELECT coalesce(convert(varchar(10),
try_convert(date,
convert(varchar(8),
nmuloc),
112),
103),
'0')
FROM elbat;
db<>fiddle
The latter one will also correct other "malformed" data like 123 for example. The former will also fail in such cases. You may want that or not.
But, as also already pointed out in the comments, your real problem is that you use an inappropriate data type. Change the column's datatype to some date/time data type to really fix this.

SQL Server 2017 Convert Varchar to Date

I have a date stored as nvarchar which I cannot seem to convert to a date.
I have tried the following but get the error message
Conversion failed when converting date and/or time from character string
select cast([month-year] as date) from [Reporting].[AIM].[Hires_PBI]
select convert(date, [month-year], 103)from [Reporting].[AIM].[Hires_PBI]
Any ideas here?
Find the values that are causing the problem using try_convert():
select [month-year]
from [Reporting].[AIM].[Hires_PBI]
where try_convert(date, [month-year], 103) is null and
[month-year] is not null;
Once you see what values are causing the problem, you can adjust the conversion logic to convert all values. Or just use try_convert() to get NULL for the non-convertible values.

Why isn't SQL Server letting me store '21/04/17' as a date?

I've got a table that currently has all columns stored as nvarchar(max), so I'm converting all the datatypes to be what they should be. I have a column of dates, however when I run this:
ALTER TABLE Leavers ALTER COLUMN [Actual_Termination_Date] date;
I get
"Conversion failed when converting date and/or time from character string".
This is relatively normal, so I did the following to investigate:
SELECT DISTINCT TOP 20 [Actual_Termination_Date]
FROM LEAVERS
WHERE ISDATE([Actual_Termination_Date]) = 0
which returned:
NULL
13/04/2017
14/04/2017
17/04/2017
19/04/2017
21/04/2017
23/04/2017
24/04/2017
26/04/2017
28/04/2017
29/03/2017
29/04/2017
30/04/2017
31/03/2017
42795
42797
42813
42817
42820
42825
The null and excel style date formats (e.g. 42795) are no problem, however it's the ones appearing as perfectly normal dates I'm having a problem with. I usually fix issues like this by using one of the following fixes:
SELECT cast([Actual_Termination_Date] - 2 as datetime)
FROM LEAVERS
WHERE ISDATE([Actual_Termination_Date]) = 0
or
SELECT cast(convert(nvarchar,[Actual_Termination_Date], 103) - 2 as datetime)
FROM LEAVERS
WHERE ISDATE([Actual_Termination_Date]) = 0
When these return back the dates as I would expext, I'd then do an UPDATE statement to change them in the table and then convert the column type. However I keep getting an error message telling me that various dates can't be converted such as:
Conversion failed when converting the nvarchar value '21/04/2017' to data type int.
Any thoughts? Thanks!
Probably because of your language setting. For '21/04/2017' to work, you'll need to be using the BRITISH language, or other language that uses dd/MM/yyyy. I suspect you are using ENGLISH which is actually American.
American's use MM/dd/yyyy meaning that '21/04/2017' would mean the 4th day of the 21st month in the year 2017; obviously that doesn't work.
The best method is to use an unambiguous format, regardless of language and data type. For SQL Server that's yyyyMMdd and yyyy-MM-ddThh:mm:ss.nnnnnnn (yyyy-MM-dd and yyyy-MM-dd hh:mm:ss.nnnnnnn are not unambiguous in SQL Server when using the older datetime and smalldatetime data types).
Otherwise you can use CONVERT with a style code:
SELECT CONVERT(date,'21/04/2017', 103)
The problem with your data, however, is that you have values that are in the format dd/MM/yyyy and integer values. The int (not varchar) value 42817 as a datetime in SQL Server is 2017-03-25. On the other hand, if this data came from Excel then the value is 2017-03-23. I am going to assume the data came from Excel, not SQL Server (because the ACE drivers have a habit of reading dates as numbers, because the thing they aren't is "ace").
You'll need to therefore convert the values to an unambiguous format first, so that'll be yyyyMMdd. As we have 2 different types of values, this is a little harder, but still possible:
UPDATE dbo.Leavers
SET Actual_Termination_Date = CONVERT(varchar(8), ISNULL(TRY_CONVERT(date, Actual_Termination_Date, 103), DATEADD(DAY, TRY_CONVERT(int, Actual_Termination_Date),'18991230')), 112);
Then you can alter your table:
ALTER TABLE dbo.Leavers ALTER COLUMN [Actual_Termination_Date] date;
DB<>Fiddle using MichaƂ Turczyn's DML statement.
Put the column into a canonical format first, then convert:
update leavers
set Actual_Termination_Date = try_convert(date, [Actual_Termination_Date], 103);
ALTER TABLE Leavers ALTER COLUMN [Actual_Termination_Date] date;
The update will do an implicit conversion from the date to a string. The alter should be able to "undo" that implicit conversion.
Back up the table before you do this! You are likely to discover that some dates are not valid -- that is pretty much the rule when you store dates as strings although in a small minority of cases, all date strings are actually consistently formatted.
The actual date does not matter. The error happens when you try to subtract 2 from a string:
[Actual_Termination_Date] - 2
The clue comes from the error message:
Conversion failed when converting the nvarchar value '21/04/2017' to data type int.
To fix the problem, use DATEADD after the conversion:
SELECT DATEADD(days, -2, convert(datetime, [Actual_Termination_Date], 103))
You just have inconsistent date format within your column, which is terrible.
Having wrong datatype lead to it, that's why it is so important to have proper data types on columns.
Let's investigate it a little:
-- some test data
declare #tbl table (dt varchar(20));
insert into #tbl values
(NULL),
('13/04/2017'),
('14/04/2017'),
('17/04/2017'),
('19/04/2017'),
('21/04/2017'),
('23/04/2017'),
('24/04/2017'),
('26/04/2017'),
('28/04/2017'),
('29/03/2017'),
('29/04/2017'),
('30/04/2017'),
('31/03/2017'),
('42795'),
('42797'),
('42813'),
('42817'),
('42820'),
('42825');
-- here we handle one format
select convert(date, dt, 103) from #tbl
where len(dt) > 5
or dt is null
-- here we handle excel like format
select dateadd(day, cast(dt as int), '1900-01-01') from #tbl
where len(dt) = 5
So, as you can see you have to apply to different approaches for this task. CASE WHEN statement should fit here nicely, see below SELECT:
select case when len(dt) = 5 then
dateadd(day, cast(dt as int), '1900-01-01')
else convert(date, dt, 103) end
from #tbl

show data with shipmentdate bigger than today

i am trying to pulling data for all shipments with shipmentdate greater than todays date. However, I cant figure out an easy conversion of the format of the nvarchar, i get a out of range value error when trying to run this:
select *
from dbo.BAS_CT_RAW_ARCHIVE_TBL
where SHIPMENTDATE > GETDATE()
Msg 242, Level 16, State 3, Line 1 The conversion of a nvarchar data
type to a datetime data type resulted in an out-of-range value.
Try:
select *
from dbo.BAS_CT_RAW_ARCHIVE_TBL
where convert(date, SHIPMENTDATE, 103) > GETDATE()
To see how to use convert with non-standard dates see this.
Further consideration: use proper datatypes for columns, i.e. don't store dates as strings, but as date datatype - it will prevent you from having such problems.
according to your data format that got from comment below should work
select * from dbo.BAS_CT_RAW_ARCHIVE_TBL
where CONVERT(date, SHIPMENTDATE, 103) > convert(date, GETDATE())

Insert converted varchar into datetime sql

I need to insert a varchar in my table. The type in the table is a datetime so I need to convert it. I didn't think this would be to big of a problem however it keeps inserting 1900-01-01 00:00:00.000 instead of the date I want. When I do a select with my converted date it does show me the correct date.
I'll show you the code:
INSERT INTO Item (CategoryId, [Date], Content, CreatedOn)
SELECT
CategoryId, Convert(datetime, '28/11/2012', 103), Content, GetDate()
FROM
Item i
JOIN
Category c ON i.CategoryId = c.Id
JOIN
Division d ON d.Id = c.DivisionId
WHERE
Date = Convert(datetime, '31/03/2005', 103)
AND d.Id = '142aaddf-5b63-4d53-a331-8eba9b0556c4'
The where clause works perfectly and gives me the filtered items I need, all data is correctly inserted except for the converted date. The gives like I said 1900-...
If I just do the select so:
SELECT CategoryId, Convert(datetime, '28/11/2012', 103), Content, GetDate()
FROM Item i
JOIN Category c ON i.CategoryId = c.Id
JOIN Division d ON d.Id = c.DivisionId
WHERE Date = Convert(datetime, '31/03/2005', 103) AND d.Id = '142aaddf-5b63-4d53-a331-8eba9b0556c4'
I get the correct date being: 2012-11-28 00:00:00.000. I have tried to use a different conversion like:
Convert(datetime, '20121128')
But that just gives the same problem. Anyone that sees what I'm doing wrong?
Thx
If you must use a string-based date format, you should pick one that is safe and works in every SQL Server instance, regardless of date format, language and regional settings.
That format is known as ISO-8601 format and it's either
YYYYMMDD (note: **NO** dashes!)
or
YYYY-MM-DDTHH:MM:SSS
for a DATETIME column.
So instead of
Convert(datetime, '28/11/2012', 103)
you should use
CAST('20121128' AS DATETIME)
and then you should be fine.
If you're on SQL Server 2008 - you could also look into using DATE (instead of DATETIME) for cases when you only need the date (no time portion). That would be even easier than using DATETIME and having the time portion always be 00:00:00
Just wanted to throw out the fact that I found this SO Question (and many others like it) years later while trying to find the answer to my problem.
If you are troubleshooting this inside a stored procedure, the parameter of the stored procedure is where you need to modify. The programmer who created the code I'm troubleshooting had #ddt CHAR(10) and no modifications inside the stored procedure resolved the problem. I had to change the parameter to #ddt smalldatetime.