Cómo definir una relación de registros lógicos entre los artículos de tabla de mezcla (programación de la replicación con Transact-SQL)

Nota

Esta característica se quitará en una versión futura de Microsoft SQL Server. Evite utilizar esta característica en nuevos trabajos de desarrollo y tenga previsto modificar las aplicaciones que actualmente la utilizan.

La replicación de mezcla le permite definir una relación entre filas relacionadas de tablas diferentes. Esto significa que las filas se pueden procesar como una unidad transaccional durante la sincronización. Se puede definir un registro lógico entre dos artículos independientemente de que tengan una relación de filtro de combinación o no. Para obtener más información, vea Agrupar cambios en filas relacionadas con registros lógicos. Puede especificar mediante programación las relaciones de registros lógicos entre los artículos usando procedimientos almacenados de replicación.

Para definir una relación de registros lógicos sin un filtro de combinación asociado

  1. Si la publicación contiene cualquier artículo que se filtra, ejecute sp_helpmergepublicationy tenga en cuenta el valor de use_partition_groups en el conjunto de resultados.

    • Si el valor es 1, las particiones precalculadas ya se están usando.

    • Si el valor es 0, ejecute sp_changemergepublication en el Publicador de la base de datos de publicación. Especifique un valor de use_partition_groups para @property y un valor de true para @value.

      Nota

      Si la publicación no admite las particiones precalculadas, no se pueden usar registros lógicos. Para obtener más información, vea los requisitos para usar particiones precalculadas en el tema Optimizar el rendimiento de los filtros con parámetros con particiones precalculadas.

    • Si el valor es NULL, el Agente de instantáneas tiene que seguir ejecutándose para generar la instantánea inicial para la publicación.

  2. Si no existen los artículos que comprenderán el registro lógico, ejecute sp_addmergearticle en el Publicador de la base de datos de publicación. Especifique una de las siguientes opciones de resolución y detección de conflictos para el registro lógico:

    • Para detectar y resolver conflictos que se producen dentro de las filas relacionadas en el registro lógico, especifique un valor de true para @logical_record_level_conflict_detection y @logical_record_level_conflict_resolution.

    • Para usar la resolución y detección de conflictos en el nivel de filas o columnas, especifique un valor de false para @logical_record_level_conflict_detection y @logical_record_level_conflict_resolution, que es el valor predeterminado.

  3. Repita el paso 2 para cada artículo que comprenderá el registro lógico. Debe usar la misma opción de resolución y detección de conflictos para cada artículo del registro lógico. Para obtener más información, vea Detectar y resolver conflictos en registros lógicos.

  4. En la base de datos de publicación del publicador, ejecute sp_addmergefilter. Especifique @publication, el nombre de un artículo en la relación para @article, el nombre del segundo artículo para @join_articlename, un nombre para la relación para @filtername, una cláusula que define la relación entre los dos artículos para @join_filterclause, el tipo de combinación para @join_unique_key y uno de los valores siguientes para @filter_type:

    • 2: define una relación lógica.

    • 3: define una relación lógica con un filtro de combinación.

    Nota

    Si no se usa un filtro de combinación, la dirección de la relación entre los dos artículos no es importante.

  5. Repita el paso 2 para cada una de las demás relaciones de registros lógicos de la publicación.

Para cambiar la resolución y detección de conflictos para los registros lógicos

  1. Para detectar y resolver conflictos que se producen dentro de las filas relacionadas en el registro lógico:

    • En la base de datos de publicación del publicador, ejecute sp_changemergearticle. Especifique un valor de logical_record_level_conflict_detection para @property y un valor de true para @value. Especifique un valor de 1 para @force_invalidate_snapshot y @force_reinit_subscription.

    • En la base de datos de publicación del publicador, ejecute sp_changemergearticle. Especifique un valor de logical_record_level_conflict_resolution para @property y un valor de true para @value. Especifique un valor de 1 para @force_invalidate_snapshot y @force_reinit_subscription.

  2. Para usar la resolución y detección de conflictos de nivel de columna y de fila estándar:

    • En la base de datos de publicación del publicador, ejecute sp_changemergearticle. Especifique un valor de logical_record_level_conflict_detection para @property y un valor de false para @value. Especifique un valor de 1 para @force_invalidate_snapshot y @force_reinit_subscription.

    • En la base de datos de publicación del publicador, ejecute sp_changemergearticle. Especifique un valor de logical_record_level_conflict_resolution para @property y un valor de false para @value. Especifique un valor de 1 para @force_invalidate_snapshot y @force_reinit_subscription.

Para quitar una relación de registros lógicos

  1. En el Publicador de la base de datos de publicación, ejecute la consulta siguiente para devolver información sobre todas las relaciones de registros lógicos definidas para la publicación especificada:

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

    Tenga en cuenta el nombre de la relación de registros lógicos que se está quitando en la columna filtername del conjunto de resultados.

    Nota

    Esta consulta devuelve la misma información que sp_helpmergefilter; sin embargo, este procedimiento almacenado del sistema sólo devuelve información sobre las relaciones de registros lógicos que también son filtros de combinación.

  2. En la base de datos de publicación del publicador, ejecute sp_dropmergefilter. Especifique @publication, el nombre de uno de los artículos en la relación para @articley el nombre de la relación del paso 1 para @filtername.

Ejemplo

Este ejemplo habilita las particiones precalculadas en una publicación existente y crea un registro lógico que comprende los dos artículos nuevos para las tablas de SalesOrderHeader y 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.BusinessEntityID = 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