We want to implement temporal tables in SQL Server 2016. We are creating a Datawarehouse and developing Type 2 Slowly changing Dimension Tables.
For the BeginDate, we want it to be dependent on transaction date and not the current getdate time. We are reprocessing a history of transactions. Example below, customer has gym or bank status, and goes from inactive, to active, or pending, dependent on transaction date.
We currently have this.
CREATE TABLE dbo.Department
(
CustomerId int primary key,
MembershipStatus int,
TransactionDate datetime
);
We we would like to create a table like this.
CREATE TABLE dbo.DepartmentHistory
(
CustomerId int primary key,
MembershipStatus int,
TransactionDate datetime,
BeginDatetime datetime,
EndDatettime datetime
);
Example usage would be:
- first Customer Transaction on 3/5/2018 as Pending P
+------------+--------+-----------+---------+ | CustomerId | Status | BeginDate | EndDate | +------------+--------+-----------+---------+ | 1 | P | 3/5/2018 | NULL | +------------+--------+-----------+---------+
- second transaction is 4/21/2018 is Active A
+------------+--------+-----------+-----------+ | CustomerId | Status | BeginDate | EndDate | +------------+--------+-----------+-----------+ | 1 | P | 3/5/2018 | 4/21/2018 | | 1 | A | 4/21/2018 | NULL | +------------+--------+-----------+-----------+
Best Answer
Temporal tables are system-versioned1, so the only way to "manually set" the timestamp of a given history row is to alter the OS time at the moment the row is modified which... you probably don't want to do.
If you want to "manually set" time bounds on a history table so that it supports temporal query syntax, you can do so by manually applying a temporal table on top of your existing data. This is a bit tricky and requires the underlying data to conform to the temporal history versioning rules. Google is peppered with various blog posts on this from back when Temporal Tables were introduced; since I haven't played with that exact use case in a while now I'll arbitrarily link off to this one example that looks promising.
Quickie Demo
Remember that a system-versioned temporal table is actually two tables - a "now" table and a "history" table squished together...
Note that while
b_now
appears to be the "base table" and supports temporal syntax - it is just a separate object. Removing the system versioning binding between the objects reinforces this.Using this information to "manually version"
Keeping this in mind - and remembering that we can switch
SYSTEM_VERSIONING
fromON
toOFF
and backON
again, we can tell SQL Server to arbitrarily apply (and arbitrarily disregard) system versioning rules to an arbitrary pair of objects so long as...Yea, I thought you might - so try this...
...Looks a lot like
b_now
andb_history
, don't it? Too bad it's not a proper system table...Wait wut...? You can even plop a view on top of the "now" table to hide your abuse of the naming conventions.
Very carefully... that's how.
I leave it to the reader (you) to wrap up the
INSERT
/UPDATE
/DELETE
logic and relevantDROP
/re-SET
system versioning into a re-useable module.1. N.B. this is hinted at with the syntax the
period for SYSTEM_time
in the required DDL for creating a temporal table