我有一个临时表,我想使用事务复制来复制它。历史表不能有事务复制所需的主键。当我尝试复制当前表时,复制失败,因为它无法插入GENERATED ALWAYS AS ROW START
或GENERATED ALWAYS AS ROW END
列。
3 回答
微软文档指出:
快照和事务复制:仅支持未启用临时的单个发布者和启用临时的订阅者。
这是一个包含一些虚拟数据的示例时态表:
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]
表,以便时间段列值完全匹配并且不为空。之后,修改订阅者端的列以制作周期列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]));
从现在开始,发布者和订阅者将各自维护自己的系统版本化时态表。不会复制整个临时表结构,因此周期列可能不会完全对齐,具体取决于复制需要多长时间。
就我而言,关闭 SYSTEM_VERSIONING 是不够的。我还不得不删除 perdiod 列:
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]));
我们只需要复制当前表(与 Microsoft 假设的情况相反)。我们在“当前”表上创建了一个非临时索引视图,并复制了索引视图。我们跳过了视图中的系统版本列(我认为这并不重要)。