在临时表中显式设置 ValidFrom

sis*_*dog 5 sql-server temporal

我正在尝试设置临时表中当前记录的 ValidFrom 范围。我这样做是因为我正在将另一个系统(非 SQL)的历史记录重建到数据仓库中,因此当前版本的记录可能是“截至”过去的日期。如果我不能让它工作,我的后退是在历史表中添加一行来填补空白,但我认为有一种方法可以让它工作。也许有一些改变列的方法?

/******** CURRENT TIME=2018-03-10 15:32:26 *****/

CREATE TABLE TestHist(
    ID int NOT NULL,
    Name varchar(max),
    --Temporal Stuff
    ValidFrom datetime2(7) NOT NULL,
    ValidTo datetime2(7) NOT NULL
)
GO

CREATE TABLE Test(
    ID int IDENTITY(1,1) NOT NULL,
    Name varchar(max),
    --Temporal Stuff
    ValidFrom datetime2(7) GENERATED ALWAYS AS ROW START NOT NULL,
    ValidTo datetime2(7) GENERATED ALWAYS AS ROW END NOT NULL,
    PRIMARY KEY CLUSTERED (ID ASC) ,
    PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
) 
WITH( SYSTEM_VERSIONING = ON ( HISTORY_TABLE = dbo.TestHist ) )
GO

ALTER TABLE Test SET (SYSTEM_VERSIONING = OFF)
go

--THIS WORKS BUT SETS THE VALIDFROM TO CURRENT TIME
insert into Test(name) values ('fred')

--AND BTW, THIS IS HOW I LOAD THE HISTORY (THIS WORKS TOO)
insert into TestHist(ID,Name,ValidFrom,ValidTo) values (1,'joe',null,'1/1/18','1/15/18')
insert into TestHist(ID,Name,ValidFrom,ValidTo) values (1,'steve','fred','2/1/18','3/1/18')
Run Code Online (Sandbox Code Playgroud)

但问题是,它将当前 ValidFrom 时间任意设置为执行插入语句时:

select * from test
ID  Name    ParentName  ValidFrom                   ValidTo
1   fred    NULL        2018-03-10 15:32:26.4403041 9999-12-31 23:59:59.9999999
Run Code Online (Sandbox Code Playgroud)

这就是我希望我能做的:

--THIS DOESN'T WORK
insert into Test(name,ValidFrom,ValidTo) values ('fred','2/1/18','9999-12-31 23:59:59.997')
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

消息 13536,级别 16,状态 1,第 38 行
无法将显式值插入表“CodeAnalytics.dbo.Test”中的 GENERATED ALWAYS 列。对列列表使用 INSERT 可排除 GENERATED ALWAYS 列,或将 DEFAULT 插入 GENERATED ALWAYS 列。

Gag*_*nzi 4

编辑:哎呀。现在已经2019年了。不管怎样,我需要这样做,所以离开这里以防其他人发现有用。

也许这样的东西就是你正在寻找的?

CREATE TABLE TestHist(
    ID int NOT NULL,
    Name varchar(max),
    --Temporal Stuff
    ValidFrom datetime2(7) NOT NULL,
    ValidTo datetime2(7) NOT NULL
)
GO

CREATE TABLE Test(
    ID int IDENTITY(1,1) NOT NULL,
    Name varchar(max),
    --Temporal Stuff
    ValidFrom datetime2(7) GENERATED ALWAYS AS ROW START NOT NULL,
    ValidTo datetime2(7) GENERATED ALWAYS AS ROW END NOT NULL,
    PRIMARY KEY CLUSTERED (ID ASC) ,
    PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
) 
WITH( SYSTEM_VERSIONING = ON ( HISTORY_TABLE = dbo.TestHist ) )
GO

ALTER TABLE Test SET (SYSTEM_VERSIONING = OFF);

insert into TestHist(ID,Name,ValidFrom,ValidTo) values (1,'steve','2/1/18','3/1/18')
insert into TestHist(ID,Name,ValidFrom,ValidTo) values (1,'joe','1/1/18','1/15/18')

SET IDENTITY_INSERT Test ON;
insert into Test(id, name) values (1, 'fred')

--after dropping period one can update validfrom on temporal table from max history
alter table Test DROP PERIOD FOR SYSTEM_TIME;
GO
update test set validfrom =(select max(validto) from TestHist where id=test.ID);

--now add period and turn system versioning back on
alter table test ADD PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo);
GO
alter table test set (system_versioning = on (HISTORY_TABLE=dbo.TestHist));
GO

--think this gives what you want
select * from test for system_time all
Run Code Online (Sandbox Code Playgroud)