使用临时表更新 ValidFrom 和 ValidTo 字段会导致奇怪的行为

Updating ValidFrom and ValidTo fields using Temporal Tables results in weird behaviour

我试图告诉历史 table 某条记录在与其原始 ValidFromValidTo 值不同的时间跨度内“相关”,如下所示:

ALTER TABLE dbo.statusForStudents SET (SYSTEM_VERSIONING = OFF);  

update history.statusForStudents set validfrom='2020-10-25 11:12:07.40',ValidTo='2020-10-26 12:48:31.19' where ValidFrom='2020-12-03 11:12:07.40' and id=1066255

ALTER TABLE statusForStudents
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE =history.statusForStudents)); 

即:
我关掉TT,
更新相关记录,
并再次打开 TT。

这确实有效, 但是,当我更新当前值时,在 TT 再次打开后:

update statusForStudents set PrimaryStatusID=1 where id=1066255  

似乎 TT 机制由于某种原因在前一个 ValidTo 时间和下一个 ValidFrom 时间之间“跳过”了几秒钟:

我在历史上从未见过这样的差距 tables..

这是一个错误吗?
有办法克服吗?

说明

如果您更新的历史记录行在 2020-12-03 11:12:07.402020-12-03 12:12.67 期间有效,这就有意义了。开始时间与您的历史更新语句匹配...

复制

创建时间 table

create table StatusForStudents
(
    Id bigint NOT NULL PRIMARY KEY CLUSTERED
  , PrimaryStatusId int
  , SysStartTime DATETIME2 GENERATED ALWAYS AS ROW START NOT NULL
  , SysEndTime DATETIME2 GENERATED ALWAYS AS ROW END NOT NULL
  , PERIOD FOR SYSTEM_TIME (SysStartTime,SysEndTime)
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.StatusForStudentsHistory));

创造一些历史来玩

-- status = 1 for 1 sec
insert into StatusForStudents (Id, PrimaryStatusId) values (1066255, 1);
WAITFOR DELAY '00:00:01';

-- status = 100 for 2 sec
update StatusForStudents set PrimaryStatusId = 100 where Id = 1066255;
WAITFOR DELAY '00:00:02';

-- status = 3 as current status
update StatusForStudents set PrimaryStatusId = 3 where Id = 1066255;

这给了我:

-- StatusForStudents
Id      PrimaryStatusId SysStartTime                SysEndTime
------- --------------- --------------------------- ---------------------------
1066255               3 2020-12-06 19:55:40.9777475 9999-12-31 23:59:59.9999999

--StatusForStudentsHistory
Id      PrimaryStatusId SysStartTime                SysEndTime
------- --------------- --------------------------- ---------------------------
1066255               1 2020-12-06 19:55:37.9464833 2020-12-06 19:55:38.9621205
1066255             100 2020-12-06 19:55:38.9621205 2020-12-06 19:55:40.9777475

搅乱历史

ALTER TABLE dbo.statusForStudents SET (SYSTEM_VERSIONING = OFF);

-- get start date for history row with status = 100
declare @Reference datetime2;
select @Reference = h.SysStartTime
from StatusForStudentsHistory h
where h.Id = 1066255
  and h.PrimaryStatusId = 100;

-- update history row for status = 100 through start date filter
update statusForStudentsHistory
set SysStartTime = '2020-10-25 11:12:07.40',
    SysEndtime = '2020-10-26 12:48:31.19'
where Id = 1066255
  and SysStartTime = @Reference;

ALTER TABLE statusForStudents SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.StatusForStudentsHistory));

新更新

-- status = 1 as current status
update StatusForStudents set PrimaryStatusID = 1 where Id = 1066255;

这给了我:

-- StatusForStudents
Id      PrimaryStatusId SysStartTime                SysEndTime
------- --------------- --------------------------- ---------------------------
1066255               1 2020-12-06 19:55:40.9933283 9999-12-31 23:59:59.9999999

--StatusForStudentsHistory
Id      PrimaryStatusId SysStartTime                SysEndTime
------- --------------- --------------------------- ---------------------------
1066255             100 2020-10-25 11:12:07.4000000 2020-10-26 12:48:31.1900000
1066255               1 2020-12-06 19:55:37.9464833 2020-12-06 19:55:38.9621205
1066255               3 2020-12-06 19:55:40.9777475 2020-12-06 19:55:40.9933283

历史记录中状态为 1 和 3 的行之间现在似乎有 2 秒的间隔 table。但是,这恰好是持续时间为 2 秒(状态 = 100)的行已更新。在这种情况下,历史更新引入了“差距”。

结论

手动更新历史记录 table 需要更新历史记录中的相邻行 table 以避免间隙和重叠。最有可能在历史记录行移动的地方 from 和行移动的地方 to.

Fiddle 观看实际效果。