{"id":82197,"date":"2016-05-09T20:54:34","date_gmt":"2016-05-09T20:54:34","guid":{"rendered":"https:\/\/www.webstaging.red-gate.com\/simple-talk\/?p=73588"},"modified":"2018-12-12T11:13:44","modified_gmt":"2018-12-12T11:13:44","slug":"temporal-tables-part-4-synchronizing-changes-across-tables","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/temporal-tables-part-4-synchronizing-changes-across-tables\/","title":{"rendered":"Temporal Tables &#8211; Part 4 &#8211; Synchronizing changes across tables"},"content":{"rendered":"<p>So way back in June of last year, when I started this series on Temporal Tables: <a href=\"https:\/\/www.webstaging.red-gate.com\/simple-talk\/uncategorized\/temporal-tables-part-1-simple-single-table-example\/\" target=\"_blank\">Part 1 &#8211; Simple Single Table Example<\/a>, <a href=\"https:\/\/www.webstaging.red-gate.com\/simple-talk\/uncategorized\/temporal-tables-part-2-changing-history\/\" target=\"_blank\">Part 2 \u2013 Changing history<\/a>; and even in <a href=\"https:\/\/www.webstaging.red-gate.com\/simple-talk\/uncategorized\/temporal-tables-part-3-syncing-multiple-modifications\/\" target=\"_blank\">Part 3 &#8211; Synchronizing Multiple Modifications<\/a>; I only referenced one table. In this entry, I want to get down to what will actually be a common concern. I want my objects to be consistent, not just at the current point in time, but throughout all points in time.&#160; I won&#8217;t even try to mix this concern with changing history, but I imagine that it could be a major undertaking depending on the data you already have from any change log tables you have created, if you were not concerned with viewing data at previous points in time.<\/p>\n<p>In part 3, I looked at what happens when the same row, or two rows in the same table would behave. 2 tables will behave quite the same, and there is a compelling reason to be cognizant of the temporal timestamps when you are dealing with multiple tables and want to see all tables as they existed at a given point in time. <\/p>\n<p>If you were writing you own versioning, you might use a trigger and write the change. Each change you would write would have a timestamp as of the time the change was written. I won&#8217;t cover the code (in this blog, but I will in the book) that you need for keeping history of changes here, but it is a widely used pattern. When a row changes, make a copy of the deleted rows in the trigger in a table that looks like the primary table, and set the time when the change was made.<\/p>\n<p>A problem with this, if you want to see how the database looks at any point in time, you would see the progression of changes over time, which could lead to inconsistent views of the data at any given point in time. So say you have a SalesOrder and SalesOrderLineItem table, and you have a ControlTotal on the SalesOrder that needs to match the sum of the line item values for the SalesOrder. There really is no way to enforce a relationship between columns in different tables as this because SQL Server does not have delayed constraints or triggers. I will use this (what could be deemed a denormalization, depending on how it is viewed in the requirements) scenario, but not all issues will be quite so obvious.<\/p>\n<p>While we must trust the client to get the math correct or reject it, if we are going to keep temporal versions of data, it is highly important that we make sure that the views across time are consistent (even down to the microsecond if we are using a very high granularity in our start and end time columns,) in order to make coding easier. By making sure that our modifications are packaged in transactions, we can do this.<\/p>\n<p>First, let&#8217;s create our tables (and I will drop the SalesORder table we had previously and add the ControlTotal column. Note that you can&#8217;t just drop a table with versioning on, you need to turn off versioning and drop both tables.):<\/p>\n<p>ALTER TABLE Sales.SalesOrder      <br \/>&#160;&#160;&#160; SET (SYSTEM_VERSIONING = OFF);       <br \/>go       <br \/>DROP TABLE Sales.SalesOrder;       <br \/>DROP TABLE Sales.SalesOrderHistory;       <br \/>GO<\/p>\n<p>Then I will recreate the table with a change from Data to ControlTotal, and then a LineItem table that has the line total, as well as foreign key constraint to the SalesOrder table:<\/p>\n<p>SET NOCOUNT ON;      <br \/>CREATE TABLE Sales.SalesOrder      <br \/>(&#160; <br \/>&#160;&#160;&#160; SalesOrderId int NOT NULL CONSTRAINT PKSalesOrder PRIMARY KEY,       <br \/>&#160;&#160;&#160; ControlTotal DECIMAL(10,2) NOT NULL,       <br \/>&#160;&#160;&#160; ValidStartTime datetime2 (7) GENERATED ALWAYS AS ROW START,       <br \/>&#160;&#160;&#160; ValidEndTime datetime2 (7) GENERATED ALWAYS AS ROW END,       <br \/>&#160;&#160;&#160; PERIOD FOR SYSTEM_TIME (ValidStartTime, ValidEndTime)       <br \/>)&#160; <br \/>WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = Sales.SalesOrderHistory)); &#8211;Another future thought, put in a different schema? I think not, but, it intrigues me nonetheless.       <br \/>GO<\/p>\n<p>CREATE TABLE Sales.SalesOrderLineItem      <br \/>(&#160; <br \/>&#160;&#160;&#160; SalesOrderLineItemId INT NOT NULL CONSTRAINT PKSalesOrderLineItem PRIMARY KEY,       <br \/>&#160;&#160;&#160; SalesOrderId int NOT NULL CONSTRAINT FKSalesOrderLineItem$ContainsDetailsFor$SalesSalesOrder REFERENCES Sales.SalesOrder(SalesOrderId),       <br \/>&#160;&#160;&#160; LineItemNumber INT NOT NULL,       <br \/>&#160;&#160;&#160; LineItemTotal DECIMAL(10,2) NOT NULL,       <br \/>&#160;&#160;&#160; CONSTRAINT AKSalesORderLineItem UNIQUE (SalesOrderId, LineItemNumber),       <br \/>&#160;&#160;&#160; ValidStartTime datetime2 (7) GENERATED ALWAYS AS ROW START,       <br \/>&#160;&#160;&#160; ValidEndTime datetime2 (7) GENERATED ALWAYS AS ROW END,       <br \/>&#160;&#160;&#160; PERIOD FOR SYSTEM_TIME (ValidStartTime, ValidEndTime)       <br \/>)&#160; <br \/>WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = Sales.SalesOrderLineItemHistory));&#160; GO<\/p>\n<p>Now let&#8217;s do a progression of data, leaving a two second gap between operations, slowing down time a little bit like can happen in reality.<\/p>\n<p>INSERT&#160; INTO Sales.SalesOrder (SalesOrderId, ControlTotal)      <br \/>VALUES&#160; (1, 100);<\/p>\n<p>WAITFOR DELAY &#8217;00:00:02&#8242;;<\/p>\n<p>INSERT&#160; INTO Sales.SalesOrderLineItem (SalesOrderLineItemId, SalesOrderId, LineItemNumber, LineItemTotal)      <br \/>VALUES&#160; (1, 1, 1, 50);<\/p>\n<p>WAITFOR DELAY &#8217;00:00:02&#8242;;<\/p>\n<p>INSERT&#160; INTO Sales.SalesOrderLineItem (SalesOrderLineItemId, SalesOrderId, LineItemNumber, LineItemTotal)      <br \/>VALUES&#160; (2, 1, 2, 50);<\/p>\n<p>Now let&#8217;s take a look at the data, just after the insert:<\/p>\n<p>SELECT&#160; *      <br \/>FROM&#160;&#160;&#160; Sales.SalesOrder       <br \/>WHERE&#160;&#160; SalesOrderId = 1;       <br \/>SELECT&#160; *       <br \/>FROM&#160;&#160;&#160; Sales.SalesOrderHistory       <br \/>WHERE&#160;&#160; SalesOrderId = 1;<\/p>\n<p>SELECT&#160; *      <br \/>FROM&#160;&#160;&#160; Sales.SalesOrderLineItem       <br \/>WHERE&#160;&#160; SalesOrderId = 1;       <br \/>SELECT&#160; *       <br \/>FROM&#160;&#160;&#160; Sales.SalesOrderLineItemHistory       <br \/>WHERE&#160;&#160; SalesOrderId = 1;<\/p>\n<p>We have 3 rows in the base tables, starting at three different times, and no history yet:<\/p>\n<p>SalesOrderId ControlTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidStartTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidEndTime      <br \/>&#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 \/>1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 100.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:36:51.1670200 9999-12-31 23:59:59.9999999<\/p>\n<p>SalesOrderId ControlTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidStartTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidEndTime      <br \/>&#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;<\/p>\n<p>SalesOrderLineItemId SalesOrderId LineItemNumber LineItemTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidStartTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidEndTime      <br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212; &#8212;&#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;       <br \/>1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 50.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:36:53.2000286 9999-12-31 23:59:59.9999999       <br \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 50.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:36:55.2452606 9999-12-31 23:59:59.9999999<\/p>\n<p>SalesOrderLineItemId SalesOrderId LineItemNumber LineItemTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidStartTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidEndTime      <br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212; &#8212;&#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;<\/p>\n<p>Now, even before we have any version history, the timestamps start to matter. Looking at current data, no problem    <\/p>\n<p>SELECT ControlTotal, LineItemTotal      <br \/>FROM&#160;&#160; Sales.SalesOrder       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; JOIN Sales.SalesOrderLineItem       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ON SalesOrderLineItem.SalesOrderId = SalesOrder.SalesOrderId<\/p>\n<p>&#160; <br \/>The results look just like you expect. But what if we are doing temporal queries on the table?      <\/p>\n<p>ControlTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; LineItemTotal      <br \/>&#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 \/>100.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 50.00       <br \/>100.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 50.00<\/p>\n<p>At the time the first operation:<\/p>\n<p>   DECLARE @asOfTime datetime2(7) = &#8216;2016-05-01 20:36:52&#8217;;   <\/p>\n<p>SELECT ControlTotal, LineItemTotal      <br \/>FROM&#160;&#160; Sales.SalesOrder FOR SYSTEM_TIME AS OF @asOfTime       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; LEFT OUTER JOIN Sales.SalesOrderLineItem FOR SYSTEM_TIME&#160; AS OF @asOfTime       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ON SalesOrderLineItem.SalesOrderId = SalesOrder.SalesOrderId;<\/p>\n<p>The data looks wrong:<\/p>\n<p>ControlTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; LineItemTotal      <br \/>&#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 \/>100.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; NULL<\/p>\n<p>And at 20:36:54:<\/p>\n<p>DECLARE @asOfTime datetime2(7) = &#8216;2016-05-01 20:36:54&#8217;;<\/p>\n<p>SELECT ControlTotal, LineItemTotal      <br \/>FROM&#160;&#160; Sales.SalesOrder FOR SYSTEM_TIME AS OF @asOfTime       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; LEFT OUTER JOIN Sales.SalesOrderLineItem FOR SYSTEM_TIME&#160; AS OF @asOfTime       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ON SalesOrderLineItem.SalesOrderId = SalesOrder.SalesOrderId;       <\/p>\n<p>Things are better, but not quite right:<\/p>\n<p>ControlTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; LineItemTotal      <br \/>&#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 \/>100.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 50.00<\/p>\n<p>Naturally, the likelihood of coming up against such a condition in the case of one row over two seconds is pretty slim, But the more concurrent operations using temporal, the more likely that you get back some weird totals that you don&#8217;t want. And even more of a concern is that users often need to fix some data that is broken when you have these inter-table dependencies. If you are fixing data, you may need to fix history as well now (fixing history is an interesting topic that I may discuss some day. The central question will be based on requirements. It really depends if you want to see the data through time, or the information through time. Information should be correct. Data is what it was.<\/p>\n<p>This time, for the second SalesOrder,&#160; I will make sure that all of the data is inserted and updated in the same transaction to ensure that the view of the data remains consistent:<\/p>\n<p>BEGIN TRANSACTION;<\/p>\n<p>INSERT&#160; INTO Sales.SalesOrder (SalesOrderId, ControlTotal)      <br \/>VALUES&#160; (2, 100);<\/p>\n<p>WAITFOR DELAY &#8217;00:00:02&#8242;;<\/p>\n<p>INSERT&#160; INTO Sales.SalesOrderLineItem (SalesOrderLineItemId, SalesOrderId, LineItemNumber, LineItemTotal)      <br \/>VALUES&#160; (3, 2, 1, 50);<\/p>\n<p>WAITFOR DELAY &#8217;00:00:02&#8242;;<\/p>\n<p>INSERT&#160; INTO Sales.SalesOrderLineItem (SalesOrderLineItemId, SalesOrderId, LineItemNumber, LineItemTotal)      <br \/>VALUES&#160; (4, 2, 2, 50);<\/p>\n<p>COMMIT TRANSACTION<\/p>\n<p>Then checking the data:<\/p>\n<p>SELECT&#160; *      <br \/>FROM&#160;&#160;&#160; Sales.SalesOrder       <br \/>WHERE&#160;&#160; SalesOrderId = 2;       <br \/>SELECT&#160; *       <br \/>FROM&#160;&#160;&#160; Sales.SalesOrderHistory       <br \/>WHERE&#160;&#160; SalesOrderId = 2;<\/p>\n<p>SELECT&#160; *      <br \/>FROM&#160;&#160;&#160; Sales.SalesOrderLineItem       <br \/>WHERE&#160;&#160; SalesOrderId = 2;       <br \/>SELECT&#160; *       <br \/>FROM&#160;&#160;&#160; Sales.SalesOrderLineItemHistory       <br \/>WHERE&#160;&#160; SalesOrderId = 2;<\/p>\n<p>&#160;<\/p>\n<p>   It is clear to see that no matter what the AS OF time used, you will not have the issue with illogical results, since all of the start and end times are the same to 7 decimal places:   <\/p>\n<p>SalesOrderId ControlTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidStartTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidEndTime      <br \/>&#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 \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 100.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:48:30.0154948 9999-12-31 23:59:59.9999999<\/p>\n<p>SalesOrderId ControlTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidStartTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidEndTime      <br \/>&#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;<\/p>\n<p>SalesOrderLineItemId SalesOrderId LineItemNumber LineItemTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidStartTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidEndTime      <br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212; &#8212;&#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;       <br \/>3&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 50.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:48:30.0154948 9999-12-31 23:59:59.9999999       <br \/>4&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 50.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:48:30.0154948 9999-12-31 23:59:59.9999999<\/p>\n<p>SalesOrderLineItemId SalesOrderId LineItemNumber LineItemTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidStartTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidEndTime      <br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212; &#8212;&#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;<\/p>\n<p>Finally, let&#8217;s update the line item 1 row to 25, and the total to be 75       <\/p>\n<p>BEGIN TRANSACTION;<\/p>\n<p>UPDATE Sales.SalesOrder      <br \/>SET&#160; ControlTotal = 75       <br \/>WHERE SalesOrderId = 2;<\/p>\n<p>UPDATE Sales.SalesOrderLineItem      <br \/>SET LineItemTotal = 25       <br \/>WHERE SalesOrderId = 2       <br \/>AND LineItemNumber = 1;<\/p>\n<p>COMMIT TRANSACTION;      <\/p>\n<p>Looking at the data and history:         <\/p>\n<p>SELECT&#160; *       <br \/>FROM&#160;&#160;&#160; Sales.SalesOrder       <br \/>WHERE&#160;&#160; SalesOrderId = 2;       <br \/>SELECT&#160; *       <br \/>FROM&#160;&#160;&#160; Sales.SalesOrderHistory       <br \/>WHERE&#160;&#160; SalesOrderId = 2;<\/p>\n<p>SELECT&#160; *      <br \/>FROM&#160;&#160;&#160; Sales.SalesOrderLineItem       <br \/>WHERE&#160;&#160; SalesOrderId = 2;       <br \/>SELECT&#160; *       <br \/>FROM&#160;&#160;&#160; Sales.SalesOrderLineItemHistory       <br \/>WHERE&#160;&#160; SalesOrderId = 2;<\/p>\n<p>We see that the SalesOrder and line time 1 start times match, but not the 4th one, as you would expect since we did not apply any modification statement to that row:       <\/p>\n<p>SalesOrderId ControlTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidStartTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidEndTime      <br \/>&#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 \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 75.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <strong>2016-05-01 20:52:41.6210321<\/strong> 9999-12-31 23:59:59.9999999<\/p>\n<p>SalesOrderId ControlTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidStartTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidEndTime      <br \/>&#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 \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 100.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:48:30.0154948 2016-05-01 20:52:41.6210321<\/p>\n<p>SalesOrderLineItemId SalesOrderId LineItemNumber LineItemTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidStartTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidEndTime      <br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212; &#8212;&#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;       <br \/>3&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 25.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <strong>2016-05-01 20:52:41.6210321<\/strong> 9999-12-31 23:59:59.9999999       <br \/>4&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 50.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:48:30.0154948 9999-12-31 23:59:59.9999999<\/p>\n<p>SalesOrderLineItemId SalesOrderId LineItemNumber LineItemTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidStartTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidEndTime      <br \/>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; &#8212;&#8212;&#8212;&#8212; &#8212;&#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;       <br \/>3&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 50.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:48:30.0154948 2016-05-01 20:52:41.6210321<\/p>\n<p>Now we can check the data as of a few times, and see that things are consistent:<\/p>\n<p>At the original time of insert:<\/p>\n<p>DECLARE @asOfTime datetime2(7) = &#8216;2016-05-01 20:48:30.0154948&#8217;;<\/p>\n<p>SELECT ControlTotal, LineItemTotal      <br \/>FROM&#160;&#160; Sales.SalesOrder FOR SYSTEM_TIME AS OF @asOfTime       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; LEFT OUTER JOIN Sales.SalesOrderLineItem FOR SYSTEM_TIME&#160; AS OF @asOfTime       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ON SalesOrderLineItem.SalesOrderId = SalesOrder.SalesOrderId       <br \/>WHERE SalesOrder.SalesOrderId = 2;<\/p>\n<p>Two rows returned, total matches line item totals:<\/p>\n<p>ControlTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; LineItemTotal      <br \/>&#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 \/>100.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 50.00       <br \/>100.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 50.00<\/p>\n<p>At the time of the update:<\/p>\n<p>DECLARE @asOfTime datetime2(7) = &#8216;2016-05-01 20:52:41.6210321&#8217;;<\/p>\n<p>SELECT ControlTotal, LineItemTotal      <br \/>FROM&#160;&#160; Sales.SalesOrder FOR SYSTEM_TIME AS OF @asOfTime       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; LEFT OUTER JOIN Sales.SalesOrderLineItem FOR SYSTEM_TIME&#160; AS OF @asOfTime       <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ON SalesOrderLineItem.SalesOrderId = SalesOrder.SalesOrderId       <br \/>WHERE SalesOrder.SalesOrderId = 2;<\/p>\n<p>This returns:<\/p>\n<p>ControlTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; LineItemTotal      <br \/>&#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 \/>75.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 25.00       <br \/>75.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 50.00<\/p>\n<p>I will leave it to you to try other times for yourself. <\/p>\n<p>One quick note, if I had updated SalesOrderLineItemId = 4, even to the same value, I would get version rows. Be really careful not to just update rows repeatedly if there is    <br \/>no change. You will want to do what you can to avoid it, or you could get this to occur:     <\/p>\n<p>UPDATE Sales.SalesOrder      <br \/>SET&#160;&#160;&#160; SalesOrderId = SalesOrderId       <br \/>WHERE&#160; SalesOrderId = 2       <br \/>GO 10<\/p>\n<p>Beginning execution loop      <br \/>Batch execution completed 10 times.<\/p>\n<p>So now the row has been updated 10 times with no change to the data. The version history is now considerably larger:<\/p>\n<p>SELECT&#160; *      <br \/>FROM&#160;&#160;&#160; Sales.SalesOrderHistory       <br \/>WHERE&#160;&#160; SalesOrderId = 2;<\/p>\n<p>SalesOrderId ControlTotal&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidStartTime&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ValidEndTime      <br \/>&#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 \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 100.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:48:30.0154948 2016-05-01 20:52:41.6210321       <br \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 75.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:52:41.6210321 2016-05-01 20:59:53.9903127       <br \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 75.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:59:53.9903127 2016-05-01 20:59:54.0059626       <br \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 75.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:59:54.0059626 2016-05-01 20:59:54.0215896       <br \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 75.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:59:54.0215896 2016-05-01 20:59:54.0372406       <br \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 75.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:59:54.0372406 2016-05-01 20:59:54.0372406       <br \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 75.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:59:54.0372406 2016-05-01 20:59:54.0528342       <br \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 75.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:59:54.0528342 2016-05-01 20:59:54.0528342       <br \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 75.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:59:54.0528342 2016-05-01 20:59:54.0528342       <br \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 75.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:59:54.0528342 2016-05-01 20:59:54.0528342       <br \/>2&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 75.00&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2016-05-01 20:59:54.0528342 2016-05-01 20:59:54.0684602<\/p>\n<p>Very little change in the start times, but some never the less (you can see the start and end times do change a little bit over time.) This could be a horrible feature to turn on if you have such an interface        <br \/>(as most of us probably do) where if nothing has changed and the user can press save over and over, causing update after update. So definitely watch your history tables after you turn this feature on to a new table to make sure of what is occurring.&#160; <\/p>\n","protected":false},"excerpt":{"rendered":"<p>So way back in June of last year, when I started this series on Temporal Tables: Part 1 &#8211; Simple Single Table Example, Part 2 \u2013 Changing history; and even in Part 3 &#8211; Synchronizing Multiple Modifications; I only referenced one table. In this entry, I want to get down to what will actually be&#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-82197","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\/82197","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=82197"}],"version-history":[{"count":1,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/82197\/revisions"}],"predecessor-version":[{"id":82202,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/82197\/revisions\/82202"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=82197"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=82197"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=82197"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=82197"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}