Поделиться через


Как определить связь логических записей между статьями таблицы в публикации слиянием (программирование репликации на языке Transact-SQL)

ПримечаниеПримечание

В будущей версии Microsoft SQL Server эта возможность будет удалена. Избегайте использования этой возможности в новых разработках и запланируйте изменение существующих приложений, в которых она применяется.

Репликация слиянием позволяет определить связь между связанными строками в различных таблицах. Это означает, что во время синхронизации строки могут обрабатываться как транзакционная единица. Логическая запись может быть определена между двумя статьями независимо от наличия связи фильтров соединения между ними. Дополнительные сведения см. в разделе Изменения группирования связанных строк с логическими записями. С помощью хранимых процедур репликации можно программно задать связь логических записей между статьями.

Определение связи логических записей без сопутствующего фильтра соединения

  1. Если публикация содержит фильтруемые статьи, выполните хранимую процедуру sp_helpmergepublication и проверьте значение параметра use_partition_groups в результирующем наборе.

    • Если значение равно 1, то предварительно вычисляемые секции уже используются.

    • Если значение равно 0, выполните хранимую процедуру sp_changemergepublication на издателе в базе данных публикации. Задайте use_partition_groups в качестве значения параметра @property и true в качестве значения параметра @value.

      ПримечаниеПримечание

      Если публикация не поддерживает предварительно вычисляемые секции, то логические записи использовать нельзя. Дополнительные сведения см. в подразделе «Требования к использованию предварительно вычисляемых секций» в разделе Оптимизация производительности параметризованного фильтра с помощью предварительно вычисляемых секций.

    • Если это значение NULL, то необходимо запустить агент моментальных снимков для создания исходного моментального снимка для публикации.

  2. Если статьи, входящие в логическую запись, не существуют, выполните хранимую процедуру sp_addmergearticle на издателе в базе данных публикации. Укажите один из приведенных ниже параметров определения и распознавания конфликтов в логической записи.

    • Для распознавания и разрешения конфликтов, возникающих в связанных строках логической записи, присвойте значение true параметрам @logical_record_level_conflict_detection и @logical_record_level_conflict_resolution.

    • Для использования стандартного определения и разрешения конфликтов уровня строки и столбца присвойте значение false параметрам @logical_record_level_conflict_detection и @logical_record_level_conflict_resolution (они имеют это значение по умолчанию).

  3. Повторите шаг 2 для каждой статьи, которая содержит логическую запись. Необходимо использовать в каждой статье логической записи одинаковые параметры определения и разрешения конфликтов. Дополнительные сведения см. в разделе Распознавание и разрешение конфликтов в логических записях.

  4. На издателе в базе данных публикации выполните хранимую процедуру sp_addmergefilter. Укажите @publication, имя одной статьи связи в качестве значения параметра @article, имя второй статьи в качестве значения параметра @join_articlename, имя связи в качестве значения параметра @filtername, предложение, определяющее связь между двумя статьями в качестве значения параметра @join_filterclause, тип соединения в качестве значения параметра @join_unique_key, а также одно из следующих значений параметра @filter_type:

    • 2 — определяет логическую связь;

    • 3 — определят логическую связь с фильтром соединения.

    ПримечаниеПримечание

    Фильтр соединения не используется, направление связи между двумя статьями несущественно.

  5. Повторите шаг 2 для всех оставшихся связей логических записей в публикации.

Изменение способа определения и разрешения конфликтов логических записей

  1. Для определения и разрешения конфликтов, возникающих в связанных строках логической записи, выполните следующие действия.

    • В базе данных публикации на издателе выполните процедуру sp_changemergearticle. Присвойте параметру @property значение logical_record_level_conflict_detection, а параметру @value — значение true. Укажите значение 1 для параметров @force_invalidate_snapshot и @force_reinit_subscription.

    • В базе данных публикации на издателе выполните процедуру sp_changemergearticle. Присвойте параметру @property значение logical_record_level_conflict_resolution, а параметру @value — значение true. Укажите значение 1 для параметров @force_invalidate_snapshot и @force_reinit_subscription.

  2. Для использования стандартного метода определения и разрешения конфликтов уровня строки и столбца выполните следующие действия.

    • В базе данных публикации на издателе выполните процедуру sp_changemergearticle. Укажите в параметре @property значение logical_record_level_conflict_detection, а в параметре @value — значение false. Укажите значение 1 для параметров @force_invalidate_snapshot и @force_reinit_subscription.

    • В базе данных публикации на издателе выполните процедуру sp_changemergearticle. Присвойте параметру @property значение logical_record_level_conflict_resolution, а параметру @value — значение false. Укажите значение 1 для параметров @force_invalidate_snapshot и @force_reinit_subscription.

Удаление связи логических записей

  1. На издателе в базе данных публикации выполните приведенный ниже запрос для получения сведений обо всех связях логических записей, определенных для указанной публикации:

    SELECT f.* FROM sysmergesubsetfilters AS f 
    INNER JOIN sysmergepublications AS p
    ON f.pubid = p.pubid WHERE p.[name] = @publication;
    

    Запомните имя удаляемой связи логических записей, содержащееся в столбце filtername результирующего набора.

    ПримечаниеПримечание

    Этот запрос возвращает те же сведения, что и системная хранимая процедура sp_helpmergefilter, однако системная хранимая процедура возвращает только сведения по тем связям логических записей, которые являются также фильтрами соединения.

  2. На издателе в базе данных публикации выполните хранимую процедуру sp_dropmergefilter. Укажите параметр @publication, имя одной из статей в связи в качестве значения параметра @article, а также имя связи из шага 1 в качестве значения параметра @filtername.

Пример

В этом примере разрешается использование предварительно вычисляемых секций в существующей публикации и создается логическая запись, в которую входят две новые статьи для таблиц SalesOrderHeader и SalesOrderDetail.

-- Remove ON DELETE CASCADE from FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID;
-- logical records cannot be used with ON DELETE CASCADE. 
IF EXISTS (SELECT * FROM sys.objects 
WHERE name = 'FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID')
BEGIN
    ALTER TABLE [Sales].[SalesOrderDetail] 
    DROP CONSTRAINT [FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID] 
END

ALTER TABLE [Sales].[SalesOrderDetail]  
WITH CHECK ADD CONSTRAINT [FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID] 
FOREIGN KEY([SalesOrderID])
REFERENCES [Sales].[SalesOrderHeader] ([SalesOrderID])
GO

DECLARE @publication    AS sysname;
DECLARE @table1 AS sysname;
DECLARE @table2 AS sysname;
DECLARE @table3 AS sysname;
DECLARE @salesschema AS sysname;
DECLARE @hrschema AS sysname;
DECLARE @filterclause AS nvarchar(1000);
DECLARE @partitionoption AS bit;
SET @publication = N'AdvWorksSalesOrdersMerge'; 
SET @table1 = N'SalesOrderDetail'; 
SET @table2 = N'SalesOrderHeader'; 
SET @salesschema = N'Sales';
SET @hrschema = N'HumanResources';
SET @filterclause = N'Employee.LoginID = HOST_NAME()';

-- Ensure that the publication uses precomputed partitions.
SET @partitionoption = (SELECT [use_partition_groups] FROM sysmergepublications 
    WHERE [name] = @publication);
IF @partitionoption <> 1
BEGIN
    EXEC sp_changemergepublication 
        @publication = @publication, 
        @property = N'use_partition_groups', 
        @value = 'true',
        @force_invalidate_snapshot = 1;
END  

-- Add a filtered article for the Employee table.
EXEC sp_addmergearticle 
  @publication = @publication, 
  @article = @table1, 
  @source_object = @table1, 
  @type = N'table', 
  @source_owner = @hrschema,
  @schema_option = 0x0004CF1,
  @description = N'article for the Employee table',
  @subset_filterclause = @filterclause;

-- Add an article for the SalesOrderHeader table.
EXEC sp_addmergearticle 
  @publication = @publication, 
  @article = @table2, 
  @source_object = @table2, 
  @type = N'table', 
  @source_owner = @salesschema,
  @schema_option = 0x0034EF1,
  @description = N'article for the SalesOrderHeader table';

-- Add an article for the SalesOrderDetail table.
EXEC sp_addmergearticle 
  @publication = @publication, 
  @article = @table3, 
  @source_object = @table3, 
  @source_owner = @salesschema,
  @description = 'article for the SalesOrderDetail table', 
  @identityrangemanagementoption = N'auto', 
  @pub_identity_range = 100000, 
  @identity_range = 100, 
  @threshold = 80;

-- Add a merge join filter between Employee and SalesOrderHeader.
EXEC sp_addmergefilter 
  @publication = @publication, 
  @article = @table2, 
  @filtername = N'SalesOrderHeader_Employee', 
  @join_articlename = @table1, 
  @join_filterclause = N'Employee.EmployeeID = SalesOrderHeader.SalesPersonID', 
  @join_unique_key = 1, 
  @filter_type = 1, 
  @force_invalidate_snapshot = 1, 
  @force_reinit_subscription = 1;

-- Create a logical record relationship that is also a merge join 
-- filter between SalesOrderHeader and SalesOrderDetail.
EXEC sp_addmergefilter 
  @publication = @publication, 
  @article = @table3, 
  @filtername = N'LogicalRecord_SalesOrderHeader_SalesOrderDetail', 
  @join_articlename = @table2, 
  @join_filterclause = N'[SalesOrderHeader].[SalesOrderID] = [SalesOrderDetail].[SalesOrderID]', 
  @join_unique_key = 1, 
  @filter_type = 3, 
  @force_invalidate_snapshot = 1, 
  @force_reinit_subscription = 1;
GO