Where we are going, we need to keep track of the history in the tables.

How to set up and use Temporal Tables in Microsoft SQL Microsoft SQL has native support for keeping track of Insert / Update / Delete from system versioned tables. The following explains how to set up and use temporal tables in Microsoft SQL.

Temporal Table

Create Schema

Create a schema that will hold all of the history tables.

Create Table

Create the first table that will have history, will load sample data from AdventureWorks database.

Alter Existing Table

Need to alter the existing table

Populate Table

Data comes from AdventureWorks database. Feel free to substitute your own.

View Initial Data

Make sure the data was added correctly

Update the Address Table

When updating rows will be inserted into the history.HomeAddress table.

View Updated Data

Select query to show the updated data. The EffectiveTo date has a value of 9999-12-31

View Historical Data

Now show previous values. You can see the date ranges applied to EffectiveFrom and EffectiveTo

Select Values as of Specified Date

Join Temporal Tables

Create a Second Temporal Table

Populate with Initial Values

Update the Record

Update the record and create some records in the history.Company table

View Current and Historical Records

Modify Company History Records

Will need to turn off system versioning and after updating turn the system versioning back on.

View the Changes

Modify the Home Address History Table

Same process as modify the company table.

View the Changes

Query the Temporal Tables

Modifiers for History Table

ExpressionQualifying RowsNote
AS OF date_timeValidFrom <= date_time AND ValidTo > date_timeReturns a table with rows containing the values that were current at the specified point in time in the past. Internally, a union is performed between the temporal table and its history table and the results are filtered to return the values in the row that was valid at the point in time specified by the date_time parameter. The value for a row is deemed valid if the system_start_time_column_name value is less than or equal to the date_time parameter value and the system_end_time_column_name value is greater than the date_time parameter value.
FROM start_date_time TO end_date_timeValidFrom < end_date_time AND ValidTo > start_date_timeReturns a table with the values for all row versions that were active within the specified time range, regardless of whether they started being active before the start_date_time parameter value for the FROM argument or ceased being active after the end_date_time parameter value for the TO argument. Internally, a union is performed between the temporal table and its history table. The results are filtered to return the values for all row versions that were active at any time during the time range specified. Rows that stopped being active exactly on the lower boundary defined by the FROM endpoint aren’t included, and records that became active exactly on the upper boundary defined by the TO endpoint are also not included.
BETWEEN start_date_time AND end_date_timeValidFrom <= end_date_time AND ValidTo > start_date_timeSame as previous in the FOR SYSTEM_TIME FROM start_date_time TO end_date_time description, except the table of rows returned includes rows that became active on the upper boundary defined by the end_date_time endpoint.
CONTAINED IN (start_date_time, end_date_time)ValidFrom >= start_date_time AND ValidTo <= end_date_timeReturns a table with the values for all row versions that were opened and closed within the specified time range defined by the two period values for the CONTAINED IN argument. Rows that became active exactly on the lower boundary or ceased being active exactly on the upper boundary are included.
ALL
All rows
Returns the union of rows that belong to the current and the history table.
ExpressionExample
AS OF date_timeSELECT *
FROM dbo.Table_Name
FOR SYSTEM_TIME AS OF ‘2023-01-01’
FROM start_date_time TO end_date_timeSELECT *
FROM dbo.Table_Name
FOR SYSTEM_TIME FROM ‘2023-01-01’ TO ‘2023-12-31’
BETWEEN start_date_time AND end_date_timeSELECT *
FROM dbo.Table_Name
FOR SYSTEM_TIME BETWEEN ‘2023-01-01’ AND ‘2023-12-31’
CONTAINED IN (start_date_time, end_date_time)SELECT *
FROM dbo.Table_Name
FOR SYSTEM_TIME CONTAINED IN (‘2023-01-01’, ‘2023-12-31’)
ALLSELECT *
FROM dbo.Table_Name
FOR SYSTEM_TIME ALL

Examples

Example 1

Expected Result

— 2022-07-15
— HoneyStore / Winnie T. / Station E

Example 2

Expected Result

— 2022-08-01
— Bucket Store / Eeyore D. / Station E

Example 3

Expected Result

— 2022-08-15
— Bucket Store / Eeyore D. / 456 Iron Way

Remove Temporal Tables

Turn System Versioning off, which will then allow you to drop the tables.