How can I find out which data won't cast? - sql

I have a SQL table with a date field defined as char(8), or 20090609, and a time field defined as char(4), or 1230. I am moving this data into another table and I want to combine the two fields and put them in a smalldatetime field in the new table. My query is like this:
INSERT NewTable(eventdate)
SELECT
CAST((datecol + ' ' + substring(timecol, 1, 2) + ':' + substring(timecol, 3, 2)) as smalldatetime)
FROM OldTable
When I run this, I get an error:
The conversion of char data type to
smalldatetime data type resulted in an
out-of-range smalldatetime value.
I've tried checking len(datecol) and len(timecol) to make sure that they are at least the correct number of characters. I have no idea how I can find the offending data, any suggestions? The database is SQL2000 and I'm using SMO 2008.

Try this:
SELECT datecol, timecol
FROM OldTable
WHERE ISDATE(datecol + ' ' + substring(timecol, 1, 2) + ':' + substring(timecol, 2, 2)) = 0
That will show you which rows cannot be converted successfully.

It is probably out of the range of acceptable smalldatetime values
January 1, 1900, through June 6, 2079
EDIT On closer inspection I think the substring parameters for the second portion of the time may be incorrect (which may be the whole problem) updated below to reflect substring(timecol, 3, 2)
New Approach this sql does assume that all dates are 8 characters in length, and all times are 4.
Select SubString(DateCol, 1, 4) as tehYear,
Substring(DateCol, 5,2) as tehMonth,
SubString(DateCol, 7,2) as tehDay,
SubString(TimeCol, 1,2) as tehHour,
Substring(TimeCOl, 3,4) as tehMinute,
*
from OldTable
where
(SubString(DateCol, 1,4) > 9999 or SubString(DateCol, 1,4) < 1753)
OR (Substring(DateCol, 5,2) > 12 or Substring(DateCol, 5,2) < 1)
OR (SubString(DateCol, 7,2) > 31 or SubString(DateCol, 7,2) < 1)
OR (SubString(TimeCol, 1,2) > 23 or(SubString(TimeCol, 1,2) < 0)
OR (Substring(TimeCOl, 3,4) > 59 or Substring(TimeCOl, 3,4) <0)
Try casting to datetime and seeing if there are any dates that fall outside of that range to identify your problem data.
SELECT
CAST((datecol + ' ' + substring(timecol, 1, 2) + ':' + substring(timecol, 3, 2))
as datetime)
FROM OldTable
Where CAST((datecol + ' ' + substring(timecol, 1, 2)
+ ':' + substring(timecol, 3, 2)) as datetime)
> Cast('06/06/2079' as datetime) or CAST((datecol + ' '
+ substring(timecol, 1, 2) + ':' + substring(timecol, 3, 2)) as datetime)
< Cast('01/01/1900' as datetime)

If you run the query in query analyzer it should tell you what row the error occured!

Related

Convert BigInt timestamp to just Date in SQL

I am facing a problem in conversion and type cast. I've a field which is of Data Type BigInt that has a value stored in the format "yyyymmddhhmmss" like "20170609043000". I am trying to get the substring of date part in the timestamp like 20170609 with a separator as 2017-06-09. Not able to fetch the date part in the timestamp.
Query I tried to fetch the Date part:
SELECT CONVERT(date,SUBSTRING(CAST(STR(evt.StartDate,15) as varchar),1, 5), 102) from Event evt
SELECT DATEADD(hour,-5, CONVERT(datetime, SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar),6, 2) + '-' + SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 8, 2) + '-' + SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 1,5) + ' ' + SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar),10, 2) + ':' +SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 12, 2) + ':' + SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 14, 2), 120)) from Event evt
The first query returns the converted date but the month and date remains same , concatenation doesn't work if I try to substring month and date.
Second query doesn't work at all.
Any help would be great.
Why not just take the 8 left most characters, and convert it?
SELECT CONVERT(date, LEFT(20170609043000,8));
Ideally though, you should be using a date and time datatype to store your date and time data. Storing them in a different data type only ends up causing problems and never solves a problem that can't be solved else where (aka your presentation layer).
Your second query is almost right but is getting the year, month, date in the wrong order. Try this instead:
SELECT CONVERT(datetime, SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar),2, 4) + '-' +
SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 6, 2) + '-' +
SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 8,2) + ' ' +
SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar),10, 2) + ':' +
SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 12, 2) + ':' +
SUBSTRING(CAST(STR(evt.StartDate, 15) as varchar), 14, 2), 120)
FROM Event evt
Output:
09/06/2017 04:30:00
Demo on dbfiddle

SQL Server : converting varchar field to date

I have in my table a varchar column with bunch of dates in the following format dd-MM-yyyy
31-12-2018
01-01-2019
02-01-2019
I need to write a date based query that gets all the dates before 01-01-2019.
I have tried using both CAST and CONVERT to convert these table values without luck.
Using CAST, my code is below:
SELECT
CAST('''' + SUBSTRING(arc_billed_to_date, 4, 2) + '-' + SUBSTRING(arc_billed_to_date, 1, 2) + SUBSTRING(arc_billed_to_date, 6, 5)+ '''' AS date),
CAST('''' + SUBSTRING(arc_billed_to_date, 7, 5) + '-' + SUBSTRING(arc_billed_to_date, 1, 2) + '-' + SUBSTRING(arc_billed_to_date, 4, 2) + '''' AS date),
CAST('''' + SUBSTRING(arc_billed_to_date, 7, 5) + '-' + SUBSTRING(arc_billed_to_date, 4, 2) + '-' + SUBSTRING(arc_billed_to_date, 1, 2) + '''' AS DATE),
CONVERT(DATE, '12-31-2018') AS x
FROM
wkpol
Using Convert
select Convert(datetime,'''' + SUBSTRING(arc_billed_to_date,7,5) + '-' + SUBSTRING(arc_billed_to_date,4,2) + '-' + SUBSTRING(arc_billed_to_date,1,2)+ '''',105) as x from wkpol
The error I get is
Conversion failed when converting date and/or time from character string.
Any help is appreciated.
SELECT *
FROM wkpol
WHERE convert(date, arc_billed_to_date, 103) < convert(date, '01/01/2019');
Well you are going to get many blames for using varchar field for date. Anyway, assuming it is a matter of another thread you can do the conversion like:
select * from myTable
where cast(right(arc_billed_to_date,4) +
substring(arc_billed_to_date,4,2) +
left(arc_billed_to_date,2) as date) < '20190101';
You wouldn't be using any index either.
In addition to Sean's comments, you can also set the DateFormat as DMY
Example
Declare #YourTable table (SomeCol varchar(50))
Insert Into #YourTable values
('31-12-2018')
,('01-01-2019')
,('02-01-2019')
Set DateFormat DMY
Select AsDate = try_convert(date,SomeCol)
From #YourTable
Returns
AsDate
2018-12-31
2019-01-01
2019-01-02

Date Conversion of yymmddhhmm.yymmddhhmm in SQL

I'm getting this type of data in DateandTime Column in SQl.
1803301611.1803301611
Format is yymmddhhmm.yymmddhhmm and I have to convert this data in a date format.
The DateandTime Column date type is Varchar(5)
I don't think the format of your time string can be directly converted by SQL Server. But, we can try to piece together into a format which can be. This is the closest I could come, and it required prepending a 20 in front of the year to make a full 4 digit century:
SELECT
col AS input,
CONVERT(datetime, '20' + SUBSTRING(col, 1, 2) + '-' + SUBSTRING(col, 3, 2) + '-' +
SUBSTRING(col, 5, 2) + ' ' + SUBSTRING(col, 7, 2) + ':' +
SUBSTRING(col, 9, 2), 120) AS output
FROM yourTable;
Demo
We ideally should have been able to use mask 20 without the century, but I could not get it to work.
You can do :
select *, cast(concat(cast(left(col, 6) as date), ' ',stuff(right(col, 4), 3, 0, ':')
) as datetime
) as newdatetime
from table t;

Converting an irregular varchar to datetime in sql server

I'm working on revamping a database right now, and all the datetime's are stored in varchar's formatted like so: DDMonYY hhmm (ex. 13Mar99 2032).
I don't have a lot of experience with SQL, as I only just finished my first year of college so I'm having a really hard time trying to get this to work so any help would be appreciated.
All you should need to do for your particular string is to get a colon in between the hour and minute values. Something like:
SELECT CAST(STUFF('13Mar99 2032', LEN('13Mar99 2032') - 1, 0, ':') AS datetime)
should work.
You can pick a datetime format and then shift parts of the string to match it. For example, format 7 is:
select convert(varchar(25), getdate(), 7)
-->
'Jun 23, 14'
So you can use substring to transform your string:
declare #orig varchar(30) = '13Mar99 2032'
declare #conv varchar(30)
select #conv = substring(#orig, 3, 3) + ' ' + substring(#orig, 1, 2) + ', ' +
substring(#orig, 6, 2) + ' ' + substring(#orig, 9, 2) + ':' + substring(#orig, 11, 2)
select #conv
, convert(datetime, #conv, 7)
-->
'Mar 13, 99 20:32' 1999-03-13 20:32:00.000

Retrieve duration query

I have a MS SQL 2005 server. I have a database by name STAT & 2 columns by name STARTRUN & ENDRUN and have many rows in it.
STARTRUN ENDRUN
20110910200007 20110910200017
20110910200028 20110910200037
20110910200048 20110910200057
It shows the start time and end time of an activity and is in YYYYMMDDHHMMSS format. The datatype for this column is VARCHAR. I am trying to write a SQL script where i can retrieve the duration of each activity and dump it to a csv file as shown below.
START DATE START TIME END DATE END TIME DURATION
10-09-2011 8:00:07 PM 11-09-2011 1:10:10 AM 5:10:03
Please help me.
First you'd have to find a way to convert your format to a datetime. The subquery below does that by making it look like an ODBC canonical date and then calling convert. Then you can combine more convert with datediff to get your desired output format.
select convert(varchar, startrun, 105) + ' ' +
substring(convert(varchar, startrun, 109), 13, 8) + ' ' +
substring(convert(varchar, startrun, 109), 25, 2)
, convert(varchar, endrun, 105) + ' ' +
substring(convert(varchar, endrun, 109), 13, 8) + ' ' +
substring(convert(varchar, endrun, 109), 25, 2)
, substring('0' + cast(datediff(hh, startrun, endrun)
as varchar), 1, 2) + ':' +
substring('0' + cast(datediff(mi, startrun, endrun) % 60
as varchar), 1, 2) + ':' +
substring('0' + cast(datediff(s, startrun, endrun) % 60*60
as varchar), 1, 2)
from (
select convert(datetime,
substring(startrun,1,4) + '-' +
substring(startrun,5,2) + '-' +
substring(startrun,7,2) + ' ' +
substring(startrun,9,2) + ':' +
substring(startrun,11,2) + ':' +
substring(startrun,13,2),
120) as startrun
, convert(datetime,
substring(endrun,1,4) + '-' +
substring(endrun,5,2) + '-' +
substring(endrun,7,2) + ' ' +
substring(endrun,9,2) + ':' +
substring(endrun,11,2) + ':' +
substring(endrun,13,2),
120) as endrun
from #YourTable
) as SubQueryAlias
Here's a working example at SE Data. See this question for exporting the result of a query to a CSV file.