Date functions in temporal tables - sql

Since SQL Server 2016 it is possible to automatically create Temporal Tables. I wanted to create a simple query that retrieves the data from a specified date. However, when I try to specify a date in the query like so, it gives a syntax error:
SELECT * FROM Person FOR SYSTEM_TIME AS OF GETDATE()
I even tried to convert the datatype to a datetime2, since the dates a stored like that, but it still wouldn't work:
SELECT * FROM Person FOR SYSTEM_TIME AS OF CONVERT(datetime2,GETDATE())
This problem occurrs, but when I first execute SELECT GETDATE() and then copy the text and paste it into the query, it works fine.
How can I specify a datetime with the AS OF keyword?
Thanks in advance.

Try this:
DECLARE #Date DATETIME2 = GETUTCDATE()
SELECT *
FROM Person
FOR SYSTEM_TIME AS OF #Date
Also, take a look at this article for more examples of querying temporal tables.

Related

How to create a function that can operate with the current date and a value from my table in sql

I have a Clients table with the inscriptiondate which is a date. I want to create a function that I give the value inscriptiondate(from my table) and do the value-currdate(). Is it possible?
I'm using SQL server, But I would also like to know how to do in Mysql if its different.
In MySQL you would typically do:
select datediff(curdate(), inscriptiondate) as days_between
In MS SQL, you would typically do:
select datediff(day, inscriptiondate, getdate())

How to convert date in mm/dd/yyyy format to yyyy-mm-dd hh:mi:ss.mmm

I'm inserting data into a table and before inserting I need to check if data exists.
I have a composite key consisted of two columns of datetime and int.
Before inserting I need to check if the data with the same time and id exists in the table.
The date that user is inserting is in 'mm/dd/yyyy'.
The datetime data in the table looks like this: '2016-01-12 00:00:00.000'.
The id field is int.
So, I have a query:
if not exists(select count(*) from table_1 where MyDate = #myDate and id = #id)
insert into table_1 .....
What is the right way to format the date user sends to match the datetime format in the table?
Check this sqlfiddle about how to use different date formats in your query. Might help you to solve it.
http://www.sqlfiddle.com/#!2/fd0b7/5
I am guessing that the question is about SQL Server, based on the syntax. The issues in the code snippet far transcend date formats.
First, the expression:
if not exists(select count(*) from table_1 where MyDate = #myDate and id = #id)
will never return true, because the subquery always returns one row with one column. If nothing matches, the column contains 0, which does exist.
You intend:
if not exists(select 1 from table_1 where MyDate = #myDate and id = #id)
Second, this check is not necessary if you wisely choose to have the database enforce the uniqueness constraint. So, define a unique index or constraint on the two columns:
create unique index unq_table_1_id_mydate on table_1(id, MyDate);
Now, the database won't let you insert duplicate values and no if is necessary.
Next, I would suggest that you fix the date format at the application layer. YYYY-MM-DD is an ISO standard date format and quite reasonable. However, if you don't want to do that, use convert():
insert into table_1(id, MyDate, .....)
select #id, convert(datetime, #MyDate, 101), . . .
The value in the database looks to be correct stored as a date/time value, so this should work fine.
You can use following line to convert date to required format in SQL server:
select FORMAT(#your_date, 'yyyy-MM-dd HH:mm:ss', 'en-US') from Your_Table

Convert column with data MM/DD/YYYY varchar to date in sql server?

I've found some similar questions but haven't been able to get anything to work yet. I'm very much a novice with little SQL experience.
I have a column END_DATE as Varchar(10) where all the rows follow the mm/dd/yyyy format and I would like to convert it to date. I have an empty column formatted as date if that helps. There are 36 million rows.
SELECT CONVERT(DATETIME,YourColumn,101) FROM YourTable
101 is mm/dd/yyyy format.
You zany backwards americans :)
To update your existing column
UPDATE YourTable
SET YourNewColumn = CONVERT(DATETIME,YourOldColumn,101)
Since it appears you have invalid data, use this method to isolate it:
UPDATE YourTable
SET YourNewColumn = CONVERT(DATETIME,YourOldColumn,101)
WHERE SomeTableKey BETWEEN ASmallCode AND ABiggerCode
Find a key in your table that you can use to divide up the data and try updating half the table... now halve it again and again until you find the offending data. Post the data here and we will come up with some code to allow for it.
I think you should convert END_DATE to DATETIME type, because you have 36 million rows and it will give a performance boost when you do not have to cast or convert it datetime with select statement.
To answer your question, you can do something like
select CAST(END_DATE AS DATETIME) FROM MyTable
The PARSE (SQL 2012) or CONVERT (any version) can do the conversion for you. Your UPDATE query will look something like one of these statements:
UPDATE the_table SET the_column = PARSE(end_date AS datetime2 USING 'en-US')
UPDATE the_table SET the_column = CONVERT(datetime2, end_date, 101)
DECLARE #End_DATE VARCHAR(10);
SET #End_DATE = '12/20/2013';
SELECT CAST(#End_DATE AS DATE)
RESULT: 2013-12-20
Empty Column formatted as Date, I am guessing you meant to say you have DATE datatype column and you would like to update this VARCHAR(10) date to , Date datatype column you could do something like this....
UPDATE Table_Name
SET New_End_DATE = CAST(End_DATE AS DATE)
Working SQL FIDDLE

Passing a date parameter to an in-line Table-Valued-Function is sloooww

I'm having a strange scenario with the performance of a table valued function. Basically, I have an inline table-valued-function that takes a DATETIME as a parameter.
It sort of looks like this (not exactly this):
CREATE FUNCTION fn_MyFunction(#StartDate DATETIME)
RETURNS TABLE
AS
RETURN (
SELECT COUNT(*), CustomerID, SUM(PAID)
FROM Orders
WHERE OrderDate > #StartDate
GROUP BY CustomerID
)
Now, I'm trying to investigate an issue where this query is running for >1 minute. It turns out that if I call the query this way:
SELECT * FROM fn_MyFunction('7/1/2011')
It runs for > 1 minute.
However, if I call the query this way:
DECLARE #startDate DATETIME = '7/1/2011'
SELECT * FROM fn_MyFunction(#startDate)
It runs in under a second. SQL Server is using entirely different explain plans for both calls.
Obviously, I want it to do the second method all the time, unfortunately, I'm calling this Table Valued Function through LINQ 2 SQL, which won't declare an interim variable.
Is there a way I can use an interim variable in the in-line table valued function? I don't really want to convert this to a multi-line table valued function. Other ideas would be welcome as well. I'm a little stumped.
I tried this with a large ammount of records and both ways returned the values in 9 seconds, no
diference...
this is a long shot but can test to see if the implicit cast is giving the function the same date value as the explicit cast? try with a date like '2011/1/30' so you would have month/day conversion problems
Adding OPTION (RECOMPILE) will fix your problem. I have the exact same issue with an inline TVF as follows :
This statement executes in less than a second :
select PropertyID from msa_GetPropertlyListWithNoMessages_TVF(DATEADD(hh, -2, Getdate()))
This statement never finished execution after 5 hours :
declare #msg_age as Datetime
SET #msg_age = DATEADD(hh, -2, Getdate())
select PropertyID from msa_GetPropertlyListWithNoMessages_TVF(#msg_age)
Adding OPTION (RECOMPILE) to the second call corrects the problem.
From what I can tell using the datetime parameter somehow produces a drastically different execution plan. I would be interested to find out why.

SQL Server 2005 - Add Milliseconds column onto DateTime column

How do i combine 2 column using SQL server 2005 ?
Problem is that The DateTime is stored in 1 column and the milliseconds is stored in another column.
I want to add the Milliseconds onto DateTime column to give it a more accurate DateTime.
I need to use this DateTime to query record accurate to milliseconds.
Any idea?
I need to replace DateTime with the added values.
SELECT *
FROM TABLENAME
WHERE [DateTime] >= '2011-04-12 12:00:00 AM'
AND [DateTime] <= '2011-05-25 3:35:04 AM'
and run the query.
Well, first solve your problem:
SELECT DATEADD(millisecond,<milliscolumn>,<datetimecolumn>) from <table>
And then file a bug report that these should just be stored in one column anyway.
You can do this, based on your sample query, but note that this destroys the possibility of the server being able to use an index:
SELECT * FROM TABLENAME WHERE
DATEADD(millisecond,[MillisecondColumn],[DateTime]) between
'2011-04-12T12:00:00' AND '2011-05-25T03:35:04'
If this is a large table, then indexes may be important. If you can't alter whatever's populating this data, you might want to add this calculation as a persisted computed column to this table, and then index and query against that.
Note that I've replaced your two comparisons with a single BETWEEN, and also adjusted the datetime strings so that they're not affected by regional settings.
SELECT (ColumnA + ColumnB) AS ColumnZ
FROM Table
might solve your problem.