timestamp from sap into datetime in sql - sql-server

from the beginning. I extracted data from Sap to MYSQL DB. In some tables, there are columns that were extracted as FLOAT and looks like this: 20131009012152.
As you can see it's like the string but float.
If I try to convert it into datetime, I get errors or overload etc.
I have tried CAST, CONVERT, SRT, SUBSTRING, nothing works.
Last try:
SELECT top 10 CREATED_AT,
SUBSTRING(CAST(STR(CREATED_AT, 25, 5) as varchar), 1, 4)
from databank.tablename;
-- wanted to substract parts (here, year) but I get just empty column as result.
Cast to nvarchar to datetime doesn't work. as well as nvarchar- bigint - datetime.
Hope, somebody can help me, thanks

One option, rather ugly, uses the CONVERT function with a series of string concatenations. I first get your numeric timestamp over to a string using a CTE.
WITH cte AS (
SELECT CAST(20131009012152 AS VARCHAR) num
)
SELECT
CONVERT(datetime, SUBSTRING(num, 1, 4) + '-' + SUBSTRING(num, 5, 2) + '-' +
SUBSTRING(num, 7, 2) + ' ' + SUBSTRING(num, 9, 2) + ':' +
SUBSTRING(num, 11, 2) + ':' + SUBSTRING(num, 13, 2), 120) AS the_date
FROM cte;
The verbosity of this query and your data makes me think that you probably did not export properly. Use this only if SAP really has no ability to export a proper timestamp (which I doubt).
Output:
09.10.2013 01:21:52
Demo

Found the similar way that can be directly used in SELECT:
CONVERT(datetime,
SUBSTRING(CAST(STR(COLUMN, 15) as varchar), 1,5) + '-' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar),6, 2) + '-' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar), 8, 2) + ' ' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar),10, 2) + ':' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar), 12, 2) + ':' +
SUBSTRING(CAST(STR(COLUMN, 15) as varchar), 14, 2), 120) as [COLUMN]
Result: 2017-01-01 15:33:15.000

Besides an old threat I want to share my solution:
Normally the SAP-Timestamps come like this in a char or varchar: 20220620081129
To bring it into a usable SQL format you need to stretch it into a date/datetime
format with dashes and colons.
This can be easily achieved by converting the text into a int/bigint and then
formatting this number into an output format that looks like a date.
Next step is just converting this resulting text into a datetime.
/*Code:*/
convert(datetime,format(convert(bigint,<fieldname>),'##-##-## ##:##:##'),120)
/*Example*/
DECLARE #SAPTable AS TABLE ([/BIC/XCREATE] VARCHAR(30))
INSERT INTO #SAPTable ([/BIC/XCREATE])
VALUES ('20220822144737');
SELECT convert(DATETIME, format(convert(BIGINT, [/BIC/XCREATE]), '##-##-## ##:##:##'), 120)
FROM #SAPTable
As easy as this.
Just adjust the fieldname [/BIC/XCREATE] and the output format to your needs.
In case you have other (shorter or longer) datetime values then, for sure, some things are needed to be adjusted but the principle is the same.
At the end the result is a real date value in terms of the SQL-Server and can be used anyhow.
I think that way it's easier than fiddling with substrings.

Related

SQL Server: Transfer YYYYMMDD-HHMMSS to mm/dd/yyyy hh:mm:ss

My SQL Server system is 2016.
As topic, I want to convert YYYYMMDD-HHMMSS to mm/dd/yyyy hh:mm:ss, and use dynamic SQL to fulfill this.
My data looks like this:
ID
20161119-075950
20161117-110952
20161118-153406
The datatype is nvarchar.
While I used the syntax below:
SELECT convert(date,convert(varchar(max),id,130), 130) from abc
An error Conversion failed when converting date and/or time from character string. shows up. I am thinking whether it is because SQL Server cannot identify this YYYYMMDD-HHMMSS as date type, and I need to convert this to YYYYMMDD hh:mm:ss first and then mm/dd/yyyy hh:mm:ss? Feel free to shed some lights. Thanks!
Select CONVERT(VARCHAR(25) , CAST(LEFT(ID , 8) AS DATETIME), 101)
+ ' ' + LEFT(RIGHT(ID , 6) ,2) + ':'
+ SUBSTRING(RIGHT(ID , 6) , 3,2) + ':'
+ RIGHT(ID , 2)
FROM TableName
Try it like this
DECLARE #tbl TABLE(ID NVARCHAR(100));
INSERT INTO #tbl VALUES
('20161119-075950')
,('20161117-110952')
,('20161118-153406');
--This is the actual select you need:
SELECT CAST(LEFT(ID,8) AS DATETIME) + STUFF(STUFF(RIGHT(ID,6),5,0,':'),3,0,':')
FROM #tbl
Your first part is strictly 8 chars long and implicitly casteable (unseperated datetime yyyymmdd). The time part is strictly 6 chars long. I use STUFF to insert the colons. This time can be added to a DATETIME. It will be - again implicitly - casted to DATETIME.
EDIT
To reach the given format you stated in the title just convert the first part first with code 101:
SELECT CONVERT(VARCHAR(10),CAST(LEFT(ID,8) AS DATETIME),101) + ' ' + STUFF(STUFF(RIGHT(ID,6),5,0,':'),3,0,':')
FROM #tbl
This should get the format you want... but there are probably better ways.
select
convert(varchar(16),convert(date,left(ID,8)),101) +
' ' +
substring(substring(ID,10,6),1,2) +
':' +
substring(substring(ID,10,6),3,2) +
':' + substring(substring(ID,10,6),5,2)

Convert varchar (eg. 20151125175706+0800) to Datetime in SQL

How do I convert yyyymmddhhmmss+offset (20151125175706+0800) to datetime format in SQL Server? To something that can be used in datetime comparison to select records entered in table during last one minute.
Im getting this format from OBX segment of the message and I'm saving this as is in a varchar field in table.
I tried to do this(among other things):
select cast(convert(varchar, SUBSTRING(OBXDateTime, 1, 4) + '-' +
SUBSTRING(OBXDateTime, 5, 2) + '-' +
SUBSTRING(OBXDateTime, 7, 2) + ' ' +
SUBSTRING(OBXDateTime, 9, 2) + ':' +
SUBSTRING(OBXDateTime, 11, 2) + ':' +
SUBSTRING(OBXDateTime, 13, 2), 101) as datetime) from ObservationPatInfo
This query gives only 522 rows out of 1020 rows in the table and gives as error message saying
"The conversion of a varchar data type to a datetime data type resulted in an out-of-range value."
Kindly help me to solve this.
You can try this:
DECLARE #YourDt VARCHAR(100)='20151125175706+0800';
DECLARE #ISO8601_with_TimeZone VARCHAR(100);
--This will use multiple STUFFs to get the separators into your string
SELECT #ISO8601_with_TimeZone = STUFF(STUFF(STUFF(STUFF(STUFF(STUFF(#YourDt,18,0,':'),13,0,':'),11,0,':'),9,0,'T'),7,0,'-'),5,0,'-');
--This looks like a properly formatted datetime now: 2015-11-25T17:57:06+08:00
SELECT #ISO8601_with_TimeZone;
--Use DATETIME2 and code 127 to convert ISO8601 with TimeZone
SELECT CONVERT(datetime2,#ISO8601_with_TimeZone,127);
Use TRY_CONVERT to find the bad values:
select pi.*
from (select try_convert(ddatetime,
(SUBSTRING(OBXDateTime, 1, 4) + '-' +
SUBSTRING(OBXDateTime, 5, 2) + '-' +
SUBSTRING(OBXDateTime, 7, 2) + ' ' +
SUBSTRING(OBXDateTime, 9, 2) + ':' +
SUBSTRING(OBXDateTime, 11, 2) + ':' +
SUBSTRING(OBXDateTime, 13, 2)
), 101) as datetime) as dte, pi.*
from ObservationPatInfo pi
) pi
where dte is null;

Converting SQL Server varchar to datetime for arithmetic

I want to combine two separate columns into date time and subtract 20 hours in SQL Server.
This works in Oracle:
create table t ( x varchar2(8),y varchar2(6));
insert into t values ('20151106','090000');
select to_char(to_date(x||' '||y, 'yyyymmdd hh24miss')
- (20/24),'dd-mm-yyyy hh24:mi:ss') as "date minus 20 hrs" from t;
date minus 20 hrs
- -----------------
05-11-2015 13:00:00
I can't crack it in SQL Server, I can get parts to work but can't combine the two dates (too many functions).
This works:
CREATE TABLE t (x VARCHAR(8), y VARCHAR(6))
INSERT INTO t
VALUES('20151105', '150800')
SELECT
DATEADD(HOUR, -20, CAST(CONCAT(SUBSTRING(y, 1, 2), ':', SUBSTRING(y, 3, 2), ':', SUBSTRING(y, 5, 2)) AS TIME))
FROM t
This works:
SELECT DATEADD(HOUR, -20, x)
FROM t
But I can't combine them:
SELECT
DATEADD(HOUR, -20,
CONCAT(SUBSTRING(x, 1, 4), '-', SUBSTRING(x, 5, 2), '-',
SUBSTRING(x, 7, 2), ' ',
CAST(CONCAT(SUBSTRING(y, 1, 2), ':', SUBSTRING(y, 3, 2),
':', SUBSTRING(y, 5, 2)) AS TIME)))
FROM t
If you CONVERT the values properly to a datetime, there should be no issue with what you're trying to do. You want to give SQL Server a date in the following format, or one of the other acceptable formats:
YYYYMMDD HH:MM:SS
So applying that to your sample, the date portion is fine, but you need to get the time format correct before you can convert it to a valid date:
CREATE TABLE #t ( x VARCHAR(8), y VARCHAR(6) )
INSERT INTO #t
VALUES ( '20151105', '150800' )
-- we want 20151105 15:08:00
SELECT DATEADD(HOUR, -20,
( CONVERT(DATETIME, x + ' ' +
LEFT(y, 2) + ':' +
SUBSTRING(y, 3, 2) + ':' +
RIGHT(y, 2)) )) AS Result
FROM #t
DROP TABLE #t
Produces
2015-11-04 19:08:00.000
The string you're passing to datepart evaluates to:
select dateadd(hour, -20, '2015-11-05T15:08:00.0000000')
But you'll get a Conversion failed error for more than 3 zeroes. An easy way to fix that is to remove the second column's conversion to time. While you're at it, you could use + instead of concat, which is easier to read:
select dateadd(hour, -20,
substring(x,1,4) + '-' +
substring(x,5,2) + '-' +
substring(x,7,2) + 'T' +
substring(y,1,2) + ':' +
substring(y,3,2) + ':' +
substring(y,5,2))
from t
See it working at SE Data.

VARCHAR TO DATE

Currently i have a column called date as varchar instead of date time. the format is currently 'sep12'. How can i transfer this to a date type?
I know this is the template but I'm not sure what to change the numbers to due to my current format as MMMYY.
CAST (
SUBSTRING(date, 3, 2) + '/' +
SUBSTRING(date, 1, 2) + '/' +
SUBSTRING(date, 5, 4)
AS DATETIME)
any help would be greatly appreciated
At the moment when ordering by the date field it is ordering like apr09, apr10. aug09, aug10 but I need it to be in year order
First, storing dates in this manner is a terrible idea. But if you know that the year will always start with 20 then you can use something like this (see SQL Fiddle Demo):
declare #dt varchar(10) = 'Sep12'
select convert(datetime, left(#dt, 3) + '01 20' + right(#dt, 2), 100)
If pulling data from your table:
select convert(datetime, left(yourDateField, 3) + '01 20' + right(yourDateField, 2), 100)
from yourTable

INT to hh:mm:ss tt in SQL Server

I will have an integer calculated from datediff()
let's say.. it is..
declare #earliestTime int;
set #earliestTime=50000000;
I want to convert to hh:mm:ss tt
I have this code to convert that int to HH:mm:ss
CONVERT(varchar(6), (#earliestTime)/60)+ ':' + RIGHT('0' + CONVERT(varchar(2), ((#earliestTime) % 60) ), 2)+ ':' + RIGHT('0' + CONVERT(varchar(2), ((#earliestTime) %60)*0), 2)
How can I modify it to hh:mm:ss tt (AM or PM)
I modified like this..
CONVERT(varchar(6),
case
when
((#earliestTime)/60)<=12
then
((#earliestTime)/60)
else
(((#earliestTime)/60)-12)
end )
--CONVERT(varchar(6), case when((#earliestTime)/60)<=12 then (#earliestTime)/60 else ((#earliestTime)/60)-12)
+
':'
+
RIGHT('0' + CONVERT(varchar(2), ((#earliestTime) % 60) ), 2)
+
':'
+
RIGHT('0' + CONVERT(varchar(2), ((#earliestTime) %60)*0), 2
+
' '
+
convert(varchar(2),(case when ((#earliestTime)/60)<12 then 'am' else 'pm' end)))
But it gives me this error..
Conversion failed when converting the
varchar value 'pm' to data type int.
I already convert 'pm' or 'am' to varchar(2). why the system still gives me that error?
How to make it correct or is there a better way?
You don't explain what your integer represents so it is difficult to give an answer.
It's best to use a proper data type for times. I'd use DATETIME - it will allow to you to perform calculations, sort, and format as required. Storing time as text is going to cause headaches later on.
Store a time by adding the time to the SQL epoch (1900-01-01 00:00:00), like so
SELECT DATEADD(SECOND, 50000, CONVERT(DATETIME, 0.0))
SELECT DATEADD(MINUTE, 50000, CONVERT(DATETIME, 0.0))
Then format the DATETIME object accordingly.
To get HH:mm:ss, use format 108.
To get the AM/PM flag, use 100 and take the two rightmost characters.
Try the below:
DECLARE #date DATETIME
SET #date = DATEADD(SECOND, 50000, CONVERT(DATETIME, 0.0))
SELECT CONVERT(VARCHAR, DATEPART(HOUR, #date)%12)
+ ':' + RIGHT(CONVERT(VARCHAR, #date, 108),5)
+ RIGHT(CONVERT(VARCHAR, #date, 100), 2)
I should also point out that you are working in a database, not a presentation layer. There should be no need to worry about formatting dates and times in a database; it is about data storage and retrieval. Presumably you are returning this time to an application or webpage to be put onto a screen, into a report or whatever - best practice is to keep the data as a complete DATETIME and let the top layer format it. By converting to a VARCHAR you are just removing information and limiting yourself; no benefit, lots of cost.

Resources