使用临时表更新 ValidFrom 和 ValidTo 字段会导致奇怪的行为
Updating ValidFrom and ValidTo fields using Temporal Tables results in weird behaviour
我试图告诉历史 table 某条记录在与其原始 ValidFrom
和 ValidTo
值不同的时间跨度内“相关”,如下所示:
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.40
到 2020-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 观看实际效果。
我试图告诉历史 table 某条记录在与其原始 ValidFrom
和 ValidTo
值不同的时间跨度内“相关”,如下所示:
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.40
到 2020-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 观看实际效果。