Как реплицировать темпоральную таблицу

У меня есть темпоральная таблица, и я хочу реплицировать ее с помощью репликации транзакций. Таблица истории не может иметь первичный ключ, необходимый для репликации транзакций. Когда я пытаюсь реплицировать текущую таблицу, происходит сбой репликации, поскольку она не может вставить данные в столбцы GENERATED ALWAYS AS ROW START или GENERATED ALWAYS AS ROW END.


person Steven Brown    schedule 30.07.2018    source источник


Ответы (3)


Документация Microsoft гласит:

Снимок и репликация транзакций. Поддерживается только для одного издателя без временного включения и одного подписчика с временным включением.

Вот пример темпоральной таблицы с некоторыми фиктивными данными:

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]));

С этого момента издатель и подписчик будут поддерживать свои собственные темпоральные таблицы с системной версией. Вся структура темпоральной таблицы не реплицируется, поэтому столбцы периодов могут не точно выровняться в зависимости от того, сколько времени занимает репликация.

person Steven Brown    schedule 30.07.2018

В моем случае отключения 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]));
person Tomasz Libera    schedule 09.04.2020

Нам нужно было реплицировать только текущую таблицу (в противоположность предполагаемому сценарию Microsoft). Мы создали невременное индексированное представление для «текущей» таблицы и реплицировали индексированное представление. Мы пропустили столбцы системной версии в представлении (не то чтобы я думаю, что это действительно важно).

person JediSQL    schedule 09.04.2019