{"id":82175,"date":"2015-06-29T21:26:00","date_gmt":"2015-06-29T21:26:00","guid":{"rendered":"https:\/\/www.webstaging.red-gate.com\/simple-talk\/?p=73542"},"modified":"2018-12-12T11:43:51","modified_gmt":"2018-12-12T11:43:51","slug":"temporal-tables-part-1-simple-single-table-example","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/temporal-tables-part-1-simple-single-table-example\/","title":{"rendered":"Temporal Tables \u2013 Part 1 &#8211; Simple Single Table Example"},"content":{"rendered":"<p>In my first entry in my series of posts on <a href=\"https:\/\/www.webstaging.red-gate.com\/simple-talk\/uncategorized\/time-to-start-plotting-my-2016-database-design-book\/\" target=\"_blank\">DB Design Book Topics<\/a>, I want to start with a pretty interesting topic, Temporal Tables. It is a very cool new feature that takes something that used to be very painful (capturing history of changes to a table, allowing the user to see the data at a point in time), and makes it very easy.<\/p>\n<p>So if you have a row in a table, and it is created, updated, and then deleted, knowing how the row looked at a given period of time can be very useful. I wanted to start with a very basic example, to show how thing work, and later entries in this series will expand to multiple rows and tables. <\/p>\n<p>select @@version &#8211;Features are apt to change. Test if you are using a later CTP<\/p>\n<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;    <br \/>Microsoft SQL Server 2016 (CTP3.3) &#8211; 13.0.1000.281 (X64)&nbsp;&nbsp; Jan 28 2016 15:11:40&nbsp;&nbsp; Copyright (c) Microsoft Corporation&nbsp; Enterprise Evaluation Edition (64-bit) on Windows Server 2012 R2 Standard 6.3 &lt;X64&gt; (Build 9600: ) (Hypervisor) <\/p>\n<p>First off, we need to create a workspace. I will just call the database testTemporal:<\/p>\n<p>create database testTemporal      <br \/>go       <br \/>use testTemporal       <br \/>go<\/p>\n<p>Nothing needed to be done to allow temporal, just create a database on the 2016 instance. The table needs to have a few new things, highlighted in the next example:<\/p>\n<p>create table dbo.company      <br \/>(       <br \/>&nbsp;&nbsp;&nbsp; companyId&nbsp;&nbsp;&nbsp; int identity(1,1) primary key,       <br \/>&nbsp;&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; varchar(30) unique,       <br \/>&nbsp;&nbsp;&nbsp; companyNumber char(5) unique,       <br \/>&nbsp;&nbsp;&nbsp; <b>SysStartTime datetime2 GENERATED ALWAYS AS ROW START NOT NULL, &#8211;the time when this row becomes in effect        <br \/>&nbsp;&nbsp;&nbsp; SysEndTime datetime2 GENERATED ALWAYS AS ROW END NOT NULL,&nbsp;&nbsp; &#8211;the time when this row becomes no longer in effect         <br \/>&nbsp;&nbsp;&nbsp; PERIOD FOR SYSTEM_TIME (SysStartTime,SysEndTime)&nbsp;&nbsp; <br \/><\/b>)       <br \/><b>WITH (SYSTEM_VERSIONING = ON); &#8211;Note that you can use a table of your own. More on that in a later blog entry\u2026        <br \/><\/b>go<\/p>\n<p>Simple enough, and if you want to see more about the create table syntax, check BOL here (<a title=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms174979.aspx\" href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms174979.aspx\">https:\/\/msdn.microsoft.com\/en-us\/library\/ms174979.aspx<\/a>) as this is a CTP edition and subject to change.<\/p>\n<p>So let\u2019s create a row in the table:<\/p>\n<p>insert into dbo.company (name, companyNumber)      <br \/>values (&#8216;Company1&#8242;,&#8217;00001&#8217;)<\/p>\n<p>select SCOPE_IDENTITY(); &#8211;If you don&#8217;t mess up, this will be 1. We will use this in our examples      <br \/>go<\/p>\n<p>Now we change something in the table a few times to let us have a few changes to see in the example:<\/p>\n<p>update company      <br \/>set&nbsp;&nbsp;&nbsp; name = &#8216;Company Name 1&#8217;       <br \/>where&nbsp; companyId = 1<\/p>\n<p>And update it again:<\/p>\n<p>update company      <br \/>set&nbsp;&nbsp;&nbsp; name = &#8216;Company Name 2&#8217;       <br \/>where&nbsp; companyId = 1<\/p>\n<p>This time update with no changes:<\/p>\n<p>update company      <br \/>set&nbsp;&nbsp;&nbsp; name = &#8216;Company Name 2&#8217;       <br \/>where&nbsp; companyId = 1<\/p>\n<p>To see the row exactly as it currently exists, just use a normal select statement:<\/p>\n<p>select *      <br \/>from&nbsp;&nbsp; company       <br \/>where&nbsp; companyId = 1<\/p>\n<p>You will see that looks exactly as you expect:<\/p>\n<p>companyId&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; companyNumber SysStartTime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysEndTime      <br \/>&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-05 02:15:32.7938411 9999-12-31 23:59:59.9999999<\/p>\n<p>To see all versions of the rows, use the FOR SYSTEM_TIME clause with CONTAINED IN (read more here about temporal and FOR SYSTEM_TIME): <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/dn935015(v=sql.130).aspx\">https:\/\/msdn.microsoft.com\/en-us\/library\/dn935015(v=sql.130).aspx<\/a>:<\/p>\n<p>select *      <br \/>from&nbsp;&nbsp; company&nbsp; FOR SYSTEM_TIME CONTAINED IN (&#8216;1900-01-01&#8242;,&#8217;9999-12-31 23:59:59.9999999&#8217;)       <br \/>order by SysEndTime Desc<\/p>\n<p>This returns all of the row versions that have been created:<\/p>\n<p>companyId&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; companyNumber SysStartTime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysEndTime      <br \/>&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:17:23.9396846 9999-12-31 23:59:59.9999999       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:16:48.2444199 2015-06-30 00:17:23.9396846       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:16:19.1614451 2015-06-30 00:16:48.2444199       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:15:01.6419789 2015-06-30 00:16:19.1614451<\/p>\n<p>There are a few things of note. The first SysStartTime value will be when the row is inserted. The last row will be to 9999-12-31 23:59:59.9999999. Note too that when we updated the row with no actual data changes, we still get a new version.<\/p>\n<p>Also when working with the times and the FOR SYSTEM_TIME clause, be careful to include the time up to the fractional seconds or you may not get what you expect. When using CONTAINED IN, if you don\u2019t put the nines out to all seven decimal places, you won&#8217;t get the current row due to roundoff:<\/p>\n<p>select *      <br \/>from&nbsp;&nbsp; company&nbsp; FOR SYSTEM_TIME CONTAINED IN (&#8216;1900-01-01&#8242;,&#8217;9999-12-31 23:59:59.999999&#8217;) \u2013Only six decimal places       <br \/>order by SysEndTime Desc<\/p>\n<p>companyId&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; companyNumber SysStartTime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysEndTime      <br \/>&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:16:48.2444199 2015-06-30 00:17:23.9396846       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:16:19.1614451 2015-06-30 00:16:48.2444199       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:15:01.6419789 2015-06-30 00:16:19.1614451<\/p>\n<p>The more interesting use will be to work with a row (or rows) at a certain point in time, like to get the second version from 2015-06-30 00:16:19.1614451, we will use FOR SYSTEM_TIME AS OF, which takes a datetime2 value, and returns the row where SysStartTime &gt;= PassedValue &gt; SysEndTime. (The PassedValue can also be a variable.)<\/p>\n<p>select priorCompany.*      <br \/>from&nbsp;&nbsp; company FOR SYSTEM_TIME AS OF &#8216;2015-06-30 00:16:19.1614451&#8217; as priorCompany<\/p>\n<p>Note that the time was from the SysStartTime, which also was the SysEndTime for a different row. This returns:<\/p>\n<p>companyId&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; companyNumber SysStartTime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysEndTime      <br \/>&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:16:19.1614451 2015-06-30 00:16:48.2444199<\/p>\n<p>You can also use FOR SYSTEM_TIME in a JOIN criteria and see multiple versions of the row in your query:<\/p>\n<p>select company.Name, priorCompany.Name as PriorName      <br \/>from&nbsp;&nbsp; company       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; join company FOR SYSTEM_TIME AS OF &#8216;2015-06-30 00:16:19.1614451&#8217; as priorCompany       <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; on company.companyId = priorCompany.companyId<\/p>\n<p>This will return:<\/p>\n<p>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PriorName      <br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;       <br \/>Company Name 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 1<\/p>\n<p>I expect that may be a pattern that gets used in a later blog to calculate changes since a time period! Finally, lets take a quick look at what happens in a delete:    <br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>delete from company      <br \/>where&nbsp; companyId = 1<\/p>\n<p>Now, checking the data, we see that there is no 9999 row version:<\/p>\n<p>select *      <br \/>from&nbsp;&nbsp; company&nbsp; FOR SYSTEM_TIME CONTAINED IN (&#8216;1900-01-01&#8242;,&#8217;9999-12-31 23:59:59.9999999&#8217;)<\/p>\n<p>&#8211;There are the same four rows, but now all rows have an end time in the same millienium as we live in:<\/p>\n<p>companyId&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; companyNumber SysStartTime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysEndTime      <br \/>&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:15:01.6419789 2015-06-30 00:16:19.1614451       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:16:19.1614451 2015-06-30 00:16:48.2444199       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:16:48.2444199 2015-06-30 00:17:23.9396846       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:17:23.9396846 2015-06-30 00:33:39.0978045<\/p>\n<p>So looking for a row at a past time, the row did still exist:<\/p>\n<p>select priorCompany.*      <br \/>from&nbsp;&nbsp; company FOR SYSTEM_TIME AS OF &#8216;2015-06-30 00:16:19.1614451&#8217; as priorCompany<\/p>\n<p>With the only difference being that the SysEndTime isn\u2019t what is once was:<\/p>\n<p>companyId&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; companyNumber SysStartTime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysEndTime      <br \/>&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:16:19.1614451 2015-06-30 00:16:48.2444199<\/p>\n<p>But looking at the table currently, no row:<\/p>\n<p>select *      <br \/>from&nbsp;&nbsp; company <\/p>\n<p>companyId&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; companyNumber SysStartTime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysEndTime      <br \/>&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n<p>So finally, what happens when we replace the row using the same surrogate key value? (Not discussing here if this is a good idea, or bad idea\u2026And this has led me to wonder if we can adjust history if the delete was accidental\u2026 Ah, fodder for later)<\/p>\n<p>set identity_insert dbo.company on      <br \/>go       <br \/>insert into dbo.company (companyId, name, companyNumber)       <br \/>values (1, &#8216;Company1&#8242;,&#8217;00001&#8217;)       <br \/>go       <br \/>set identity_insert dbo.company off       <br \/>go<\/p>\n<p>And then look at all of the row versions that exist now?<\/p>\n<p>select *      <br \/>from&nbsp;&nbsp; company&nbsp; FOR SYSTEM_TIME CONTAINED IN (&#8216;1900-01-01&#8242;,&#8217;9999-12-31 23:59:59.9999999&#8217;)       <br \/>order&nbsp; by SysStartTime desc<\/p>\n<p>&#8211;You can see that the row now exists, but there is now a gap between the top two rows:<\/p>\n<p>companyId&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; companyNumber SysStartTime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysEndTime      <br \/>&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:37:07.1375063 9999-12-31 23:59:59.9999999       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:17:23.9396846 2015-06-30 00:33:39.0978045       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:16:48.2444199 2015-06-30 00:17:23.9396846       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company Name 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:16:19.1614451 2015-06-30 00:16:48.2444199       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:15:01.6419789 2015-06-30 00:16:19.1614451<\/p>\n<p>Looking at the data at the current row\u2019s SysStartTime:<\/p>\n<p>select priorCompany.*      <br \/>from&nbsp;&nbsp; company FOR SYSTEM_TIME AS OF &#8216;2015-06-30 00:37:07.1375063&#8217; as priorCompany<\/p>\n<p>companyId&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; companyNumber SysStartTime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysEndTime      <br \/>&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;       <br \/>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Company1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00001&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2015-06-30 00:37:07.1375063 9999-12-31 23:59:59.9999999<\/p>\n<p>But a very very small amount of time before, not there:<\/p>\n<p>select priorCompany.*      <br \/>from&nbsp;&nbsp; company FOR SYSTEM_TIME AS OF &#8216;2015-06-30 00:37:07.1375062&#8217; as priorCompany<\/p>\n<p>companyId&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; companyNumber SysStartTime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SysEndTime      <br \/>&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<\/p>\n<p>So there is a quick look at some of the basic functionality that we can expect with temporal data in 2016. <\/p>\n<p>Note: I won\u2019t be doing any guessing in these blogs because if I guess right and NDA information is out there that I missed, I could get in trouble accidentally. But I will try to make sure if there are big changes in syntax that I note it, or redo the blog syntax so I don\u2019t end up with bad information out there.<\/p>\n<p><a href=\"http:\/\/sqlblog.com\/blogs\/louis_davidson\/archive\/2015\/06\/30\/temporal-tables-part-2-changing-history.aspx\" target=\"_blank\">Continue to Part 2 \u2013 Changing History<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my first entry in my series of posts on DB Design Book Topics, I want to start with a pretty interesting topic, Temporal Tables. It is a very cool new feature that takes something that used to be very painful (capturing history of changes to a table, allowing the user to see the data&#8230;&hellip;<\/p>\n","protected":false},"author":56085,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[],"coauthors":[19684],"class_list":["post-82175","post","type-post","status-publish","format-standard","hentry","category-blogs"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/82175","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/56085"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=82175"}],"version-history":[{"count":1,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/82175\/revisions"}],"predecessor-version":[{"id":82224,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/82175\/revisions\/82224"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=82175"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=82175"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=82175"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=82175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}