Concatenate Date and Time Column of Character DataType Into DateTime DataType - tsql

Once I run the query how do I put them back together again?
I was able to run the following query to convert date value into datetime and append time part to it
declare #date char(8), #time char(8)
select #date='20101001',#time ='12:10:47'
select cast(#date as datetime)+#time
In the above method, date value is converted to datetime datatype and time value is
added to it.
--------------Output ----------------------
result tab -
(No column name )
row1 || 2011-09-16 22:16.000
How can I covert back to the original data Value(undo)??????
I ran the above query to converted to datetime datatype and time value is
added to it- worked well...Now I want to undo go back to the original date value.....

It is not clear what the question is but this is my guess. If you are trying to extract pieces of a datetime use the DatePart funciton,
declare #date char(8), #time char(8)
select #date='20101001',#time ='12:10:47'
select cast(#date as datetime)+#time
select cast(cast(#date as datetime)+#time as datetime)
select DATEPART(mm,cast(cast(#date as datetime)+#time as datetime))

To extract the constituent parts of a datetime into a string of a specific format use the CONVERT function and pass the desired style. To get back to where you started use
DECLARE #date CHAR(8),
#time CHAR(8)
SELECT #date = '20101001',
#time = '12:10:47'
DECLARE #dt DATETIME
SELECT #dt = CAST(#date AS DATETIME) + #time
SELECT CONVERT(CHAR(8), #dt, 112) AS [#date],
CONVERT(CHAR(8), #dt, 108) AS [#time]
Which gives
#date #time
-------- --------
20101001 12:10:47

Related

Adding Parameter causing issues-No data displayed

Hi all I have a stored procedure with two parameters #Startdate and #Enddate. When i execute the procedure i get data.
Now i added a parameter and it has list of values. So i added a split function and added in the WHERE clause. Now after making the changes when i execute my SP i do not get any data. I tried commenting out the 3rd Parameter from the WHERE clause and now i see the data again. Not sure what is happening. Any advice is greatly appreciated.
I have tried different split functions and Charindex(','+cast(tableid as varchar(8000))+',', #Ids) > 0 and nothing has worked.
Thanks
NOTE: The concatenation and splitting of parameter values is a poor design for performance reasons and, most importantly, very susceptible to SQL injection attacks. Please research some alternatives. If you must proceed down this path...
There are a great many split functions out there, but I used this one here to illustrate a possible solution.
CREATE FUNCTION [dbo].[fnSplitString]
(
#string NVARCHAR(MAX),
#delimiter CHAR(1)
)
RETURNS #output TABLE(splitdata NVARCHAR(MAX)
)
BEGIN
DECLARE #start INT, #end INT
SELECT #start = 1, #end = CHARINDEX(#delimiter, #string)
WHILE #start < LEN(#string) + 1 BEGIN
IF #end = 0
SET #end = LEN(#string) + 1
INSERT INTO #output (splitdata)
VALUES(SUBSTRING(#string, #start, #end - #start))
SET #start = #end + 1
SET #end = CHARINDEX(#delimiter, #string, #start)
END
RETURN
END
GO
It's unclear, from your question, if you need to filter your results based on an int, varchar or various other data types available, but here are two options (and probably the most common).
DECLARE #TableOfData TABLE
(
ID_INT INT,
ID_VAR VARCHAR(100),
START_DATE DATETIME,
END_DATE DATETIME
)
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
DECLARE #Ids VARCHAR(1000)
DECLARE #Delimiter VARCHAR(1)
SET #Delimiter = ','
SET #StartDate = GETDATE()
SET #EndDate = DATEADD(HH, 1, GETDATE())
SET #Ids = '1,2,4'
--Create some test data
INSERT INTO #TableOfData
SELECT 1, '1', GETDATE(), DATEADD(MI, 1, GETDATE()) --In our window of expected results (date + id)
UNION SELECT 2, '2', GETDATE(), DATEADD(D, 1, GETDATE()) --NOT in our window of expected results b/c of date
UNION SELECT 3, '3', GETDATE(), DATEADD(MI,2, GETDATE()) --NOT in our expected results (id)
UNION SELECT 4, '4', GETDATE(), DATEADD(MI,4, GETDATE()) --In our window of expected results (date + id)
--If querying by string, expect 2 results
SELECT TD.*
FROM #TableOfData TD
INNER JOIN dbo.fnSplitString(#Ids, #Delimiter) SS
ON TD.ID_VAR = SS.splitdata
WHERE START_DATE >= #StartDate
AND END_DATE <= #EndDate
--If querying by int, expect 2 results
SELECT TD.*
FROM #TableOfData TD
INNER JOIN dbo.fnSplitString(#Ids, #Delimiter) SS
ON TD.ID_INT = CONVERT(int, SS.splitdata)
WHERE START_DATE >= #StartDate
AND END_DATE <= #EndDate
You cannot use a parameter with a list directly in your query filter. Try storing that separated data into a table variable or temp table and call that in your query or use dynamic SQL to write your query if you don't want to use table variable or temp tables.

Extracting the number of days from a calculated interval

I am trying to get a query like the following one to work:
SELECT EXTRACT(DAY FROM INTERVAL to_date - from_date) FROM histories;
In the referenced table, to_date and from_date are of type timestamp without time zone. A regular query like
SELECT to_date - from_date FROM histories;
Gives me interval results such as '65 days 04:58:09.99'. But using this expression inside the first query gives me an error: invalid input syntax for type interval. I've tried various quotations and even nesting the query without luck. Can this be done?
SELECT EXTRACT(DAY FROM INTERVAL to_date - from_date) FROM histories;
This makes no sense. INTERVAL xxx is syntax for interval literals. So INTERVAL from_date is a syntax error, since from_date isn't a literal. If your code really looks more like INTERVAL '2012-02-01' then that's going to fail, because 2012-02-01 is not valid syntax for an INTERVAL.
The INTERVAL keyword here is just noise. I suspect you misunderstood an example from the documentation. Remove it and the expression will be fine.
I'm guessing you're trying to get the number of days between two dates represented as timestamp or timestamptz.
If so, either cast both to date:
SELECT to_date::date - from_date::date FROM histories;
or get the interval, then extract the day component:
SELECT extract(day from to_date - from_date) FROM histories;
This example demontrates the creation of a table with trigger which updates the difference between a stop_time and start_time in DDD HH24:MI:SS format where the DDD stands for the amount of dates ...
DROP TABLE IF EXISTS benchmarks ;
SELECT 'create the "benchmarks" table'
;
CREATE TABLE benchmarks (
guid UUID NOT NULL DEFAULT gen_random_uuid()
, id bigint UNIQUE NOT NULL DEFAULT cast (to_char(current_timestamp, 'YYMMDDHH12MISS') as bigint)
, git_hash char (8) NULL DEFAULT 'hash...'
, start_time timestamp NOT NULL DEFAULT DATE_TRUNC('second', NOW())
, stop_time timestamp NOT NULL DEFAULT DATE_TRUNC('second', NOW())
, diff_time varchar (20) NOT NULL DEFAULT 'HH:MI:SS'
, update_time timestamp DEFAULT DATE_TRUNC('second', NOW())
, CONSTRAINT pk_benchmarks_guid PRIMARY KEY (guid)
) WITH (
OIDS=FALSE
);
create unique index idx_uniq_benchmarks_id on benchmarks (id);
-- START trigger trg_benchmarks_upsrt_diff_time
-- hrt = human readable time
CREATE OR REPLACE FUNCTION fnc_benchmarks_upsrt_diff_time()
RETURNS TRIGGER
AS $$
BEGIN
-- NEW.diff_time = age(NEW.stop_time::timestamp-NEW.start_time::timestamp);
NEW.diff_time = to_char(NEW.stop_time-NEW.start_time, 'DDD HH24:MI:SS');
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_benchmarks_upsrt_diff_time
BEFORE INSERT OR UPDATE ON benchmarks
FOR EACH ROW EXECUTE PROCEDURE fnc_benchmarks_upsrt_diff_time();
--
-- STOP trigger trg_benchmarks_upsrt_diff_time
Just remove the keyword INTERVAL:
SELECT EXTRACT(DAY FROM to_date - from_date) FROM histories;

How can I convert this INT field to a usable date field?

The DB I am working in stores their date values as INT. I am needing to determine a date difference between two date fields but am unsure how to approach this since they are currently INT.
Dates are stored as follows: 20130101 - YYYYDDMM. Performing a DATEDIFF results in an arithmetic overflow error.
Any ideas on how to either convert two date fields or to find the date difference between them?
Select Cast( Cast( 20130101 As varchar(8) ) As datetime )
So, if you have the following two values: 20130101, 20130201, we might do the following:
Select DateDiff( d
, Cast( Cast( 20130101 As varchar(8) ) As datetime )
, Cast( Cast( 20130201 As varchar(8) ) As datetime ) )
Update
If you have values that less than 17530101 (the min value for a datetime), then you will need to use a Case expression to validate the data as it is processed. In this scenario, the use of Cast(0 As datetime) will result in 1900-01-01 as our minimum date value.
Select DateDiff( d
, Case
When Value1 <= 19000101 Then Cast(0 As datetime)
Else Cast( Cast( Value1 As varchar(8) ) As datetime )
End
, Case
When Value2 <= 19000101 Then Cast(0 As datetime)
Else Cast( Cast( Value2 As varchar(8) ) As datetime )
End )
If you are going to store the dates as integers as shown, a better idea would be to correct the data and add a check constraint that prevents values lower than 1900-01-01. If you have legitimate values lower than 1900-01-01, that will require yet another adjustment to the solution.

how convert string variable to datetime variable in sql-server?

I'm relatively new to sql-server; I'm trying to have a start-date and end-date pulled from a form-variable as string then convert it into datetime (yyyy-mm-dd) format and I can't seem to find anything that works. Attempted code and resulting error is below. Any advice would be appreciated.
declare #startdate as varchar
declare #enddate as varchar
set #startdate=cast(#startdate as datetime)
set #enddate=cast(#enddate as datetime)
SELECT order_date, inv_no
from invoices
where order_date between #startdate and #enddate
The error I keep getting is:
Conversion failed when converting datetime from character string.
How do I fix this?
specify a length for your varchar:
declare #startdate as varchar(10)
declare #enddate as varchar(10)
set #startdate=cast(#startdate as datetime)
set #enddate=cast(#enddate as datetime)
SELECT order_date, inv_no
from invoices
where order_date between #startdate and #enddate
you don't have to cast necessarily
declare #startdate varchar(50)
declare #enddate varchar(50)
declare #start datetime = #startdate, #end datetime = #enddate
select #start, #end

parser datetime via tsql

Update List
set Date = "2009-07-21T19:00:40"
sql server doesn't recognize this format. is there a conversion function
You can use CAST and CONVERT. But maybe you must replace the 'T' with a space, before you can convert it. (There are also string manipulation functions available.)
Worked just fine for me (SQL Express 2005) except for the double quotes (which SQL Server assumed was a column delimiter); is that what's throwing the error? Thanks for the sample code, but can you produce the actual error?
In other words,
DECLARE #List TABLE ( [date] DATETIME
)
INSERT INTO #List
SELECT GETUTCDATE()
UPDATE #List SET Date =
"2009-07-21T19:00:40"
produces
Msg 207, Level 16, State 1, Line 7
Invalid column name
'2009-07-21T19:00:40'.
Whereas
DECLARE #List TABLE ( [date] DATETIME
)
INSERT INTO #List
SELECT GETUTCDATE()
UPDATE #List SET Date =
'2009-07-21T19:00:40'
runs successfully.
Try this:
UPDATE List SET Date = '2009/07/21 19:00:40'
Even worked for me too(2005 & 2008)..
DECLARE #tbl TABLE ( [date] DATETIME )
INSERT INTO #tbl SELECT getdate()
select * from #tbl
UPDATE #tbl SET Date = '2009-07-21T19:00:40'
select * from #tbl
However, just give a shot with DATEFORMAT COMMAND
Something like this
**SET DATEFORMAT dmy**
DECLARE #tbl TABLE ( [date] DATETIME )
INSERT INTO #tbl SELECT getdate()
select * from #tbl
UPDATE #tbl SET Date = '2009-07-21T19:00:40'
select * from #tbl