如何复制时态表

时间:2018-07-30 19:15:04

标签: tsql transactional-replication temporal-tables

我有一个临时表,我想使用事务复制来复制它。历史记录表不能具有事务复制所需的主键。当我尝试复制当前表时,复制失败,因为它无法插入GENERATED ALWAYS AS ROW STARTGENERATED ALWAYS AS ROW END列中。

3 个答案:

答案 0 :(得分:1)

Microsoft Documentation状态:

  

快照和事务复制:仅支持未启用时间的单个发布者和启用时间的一个订户。

这是带有一些伪数据的示例时态表:

CREATE TABLE [dbo].[TemporalTest]
(
    [EmployeeID] CHAR(6) NOT NULL,
    [EmployeeName] VARCHAR(50) NOT NULL,
    [EFF_STRT_TS] DATETIME2(7) GENERATED ALWAYS AS ROW START NOT NULL,
    [EFF_END_TS] DATETIME2(7) GENERATED ALWAYS AS ROW END NOT NULL,
PERIOD FOR SYSTEM_TIME ([EFF_STRT_TS],[EFF_END_TS]),
CONSTRAINT [PK_TemporalTest] PRIMARY KEY CLUSTERED ([EmployeeID] ASC),
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[TemporalTest_HIST]));
GO

INSERT INTO [dbo].[TemporalTest]
([EmployeeID],[EmployeeName])
VALUES
    ('000001','Jane Doe'),
    ('000002','John Smith'),
    ('000003','John Deer'),
    ('000004','Dear John')

DELETE FROM [dbo].[TemporalTest]
WHERE [EmployeeID] = '000003'

UPDATE [dbo].[TemporalTest]
SET [EmployeeName] = 'Jane Smith'
WHERE [EmployeeID] = '000001'

在复制之前,请关闭SYSTEM_VERSIONING

ALTER TABLE [dbo].[TemporalTest]
SET (SYSTEM_VERSIONING = OFF);

设置事务复制,并排除期间列[EFF_STRT_TS][EFF_END_TS]。 在复制的一面,添加期间列。

ALTER TABLE [dbo].[TemporalTest]
ADD [EFF_STRT_TS] DATETIME2(7) NULL,
    [EFF_END_TS] DATETIME2(7) NULL

使用SSIS,将历史记录表[TemporalTest_HIST]从发布者复制到订阅者。同样使用SSIS,将当前[TemporalTest]表从发布者覆盖到订阅者,以便时间段列值完全匹配且不为null。然后,更改订户端的列以使周期列为NOT NULL,并将其设置为PERIOD FOR SYSTEM_TIME

ALTER TABLE [dbo].[TemporalTest]
ALTER COLUMN [EFF_STRT_TS] DATETIME2(7) NOT NULL

ALTER TABLE [dbo].[TemporalTest]
ALTER COLUMN [EFF_END_TS] DATETIME2(7) NOT NULL

ALTER TABLE [dbo].[TemporalTest]
ADD PERIOD FOR SYSTEM_TIME ([EFF_STRT_TS],[EFF_END_TS])

在发布者和订阅者这边,都设置SYSTEM_VERSIONING = ON

ALTER TABLE [dbo].[TemporalTest]
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[TemporalTest_HIST]));

从现在开始,发布者和订阅者将各自维护自己的系统版本的时态表。整个临时表结构不会被复制,因此根据复制所花费的时间,周期列可能无法完全对齐。

答案 1 :(得分:1)

就我而言,关闭SYSTEM_VERSIONING是不够的。 我还必须删除第二列:

ALTER TABLE TemporalTest DROP PERIOD FOR SYSTEM_TIME

仅在发布属性中排除它们,在订阅者初始化期间以以下错误结束

消息13504,第16级,状态1,第36行 缺少时间“一般以行开始方式生成”列。

初始化后,您需要添加期间列并打开系统版本控制

ALTER TABLE [dbo].[TemporalTest]
ADD PERIOD FOR SYSTEM_TIME ([EFF_STRT_TS],[EFF_END_TS])

ALTER TABLE [dbo].[TemporalTest]
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[TemporalTest_HIST]));

答案 2 :(得分:0)

我们只需要复制当前表(与Microsoft假定的情况相反)。我们在“当前”表上创建了一个非时间索引视图,并复制了该索引视图。我们跳过了视图中的系统版本列(不是我认为这确实很重要)。