Definir uma relação de registro lógico entre artigos da tabela de mesclagem
Este tópico descreve como definir uma relação de registro lógico entre artigos de tabela de mesclagem no SQL Server 2012 usando o SQL Server Management Studio, o Transact-SQL ou o RMO (Replication Management Objects).
A replicação de mesclagem permite definir uma relação entre linhas relacionadas em tabelas diferentes. Essas linhas podem então ser processadas como uma unidade transacional durante a sincronização. Um registro lógico pode ser definido entre dois artigos se eles tiverem ou não uma relação de filtro de junção. Para obter mais informações, consulte Agrupar alterações a linhas relacionadas com registros lógicos.
Observação |
---|
Esse recurso será removido em uma versão futura do Microsoft SQL Server. Evite usar esse recurso em desenvolvimentos novos e planeje modificar os aplicativos que atualmente o utilizam. |
Neste tópico
Antes de começar:
Limitações e restrições
Para definir uma relação de registro lógico entre artigos de tabela de mesclagem, usando:
SQL Server Management Studio
Transact-SQL
RMO (Replication Management Objects)
Antes de começar
Limitações e restrições
- Se você adicionar, modificar ou excluir um registro lógico após a inicialização de assinaturas na publicação, será preciso gerar um novo instantâneo e reinicializar todas as assinaturas depois de fazer a alteração. Para obter mais informações sobre os requisitos para alterações de propriedades, consulte Alterar propriedades da publicação e do artigo.
[Top]
Usando o SQL Server Management Studio
Defina registros lógicos na caixa de diálogo Adicionar Junção, que é fica disponibilizada no Assistente para Nova Publicação e na caixa de diálogo Propriedades de Publicação - <Publicação>. Para obter mais informações sobre como usar o assistente e acessar a caixa de diálogo, consulte Crie uma publicação e Visualizar e modificar as propriedades da publicação.
Os registros lógicos podem ser definidos na caixa de diálogo Adicionar Junção apenas se aplicados a um filtro de junção em uma publicação de mesclagem, e se a publicação atender os requisitos para uso de partições pré-calculadas. Para definir os registros lógicos que não se aplicam a filtros de junção e para definir a detecção e resolução de conflitos no nível do registro lógico, é preciso usar procedimentos armazenados.
Para definir uma relação de registro lógico.
Na página Filtrar Linhas de Tabelas do Assistente para Nova Publicação ou na página Filtrar Linhas da caixa de diálogo Propriedades de Publicação - <Publicação>, selecione um filtro de linha no painel Tabelas Filtradas.
Uma relação de registro lógico é associada a um filtro de junção que estende um filtro de linha. Por isso, é preciso definir o filtro de linha antes de poder estender o filtro com uma junção e aplicar uma relação de registro lógico. Após definir o filtro de junção é possível estendê-lo com outro filtro de junção. Para obter mais informações sobre como definir filtros de junção, consulte Definir e modificar um filtro de junção entre artigos de mesclagem.
Clique em Adicionar e depois, em Adicionar Junção para Estender o Filtro Selecionado.
Defina um filtro de junção na caixa de diálogo Adicionar Junção, depois marque a caixa de seleção Registro Lógico.
Se você estiver na caixa de diálogo Propriedades de Publicação - <Publicação>, clique em OK para salvar e fechar a caixa de diálogo.
Para excluir uma relação de registro lógico
Exclua apenas a relação de registro lógico ou exclua a relação de registro lógico e o filtro de junção a ela associado.
Para excluir apenas a relação de registro lógico:
Na página Filtrar Linhas do Assistente para Nova Publicação ou na página Filtrar Linhas da caixa de diálogo Propriedades de Publicação - <Publicação>, selecione o filtro de junção associado à relação de registro lógico no painel Tabelas Filtradas e clique em Editar.
Na caixa de diálogo Editar Junção, desmarque o caixa de seleção Registro Lógico.
Clique em OK.
Para excluir a relação de registro lógico e o filtro de junção a ela associado:
- Na página Filtrar Linhas do Assistente para Nova Publicação na caixa de diálogo Propriedades de Publicação - <Publicação>, selecione um filtro no painel Tabelas Filtradas, depois clique em Excluir. Caso o próprio filtro excluído seja estendido por outras junções, essas junções também serão excluídas.
[Top]
Usando Transact-SQL
É possível especificar relações de registro lógico de forma programática entre artigos que usem procedimentos armazenados de replicação.
Para definir uma relação de registro lógico sem filtro de junção associado
Se a publicação contiver quaisquer artigos filtrados, execute sp_helpmergepublication, e observe o valor de use_partition_groups no conjunto de resultados.
Se o valor for 1, partições pré-computadas já estarão sendo usadas.
Se o valor for 0, execute sp_changemergepublication ao Publicador do banco de dados de publicação. Especifique um valor de use_partition_groups para @property e um valor de true para @value.
Observação Se a publicação não oferecer suporte a partições pré-computadas, os registros lógicos não poderão ser usados. Para obter mais informações, consulte Requisitos para usar partições pré-computadas, no tópico Otimizar o desempenho de filtro parametrizado com partições pré-computadas.
Se o valor for NULL, será necessário executar o Snapshot Agent para gerar o instantâneo inicial para a publicação.
Se os artigos que integrarem o registro lógico não existirem, execute sp_addmergearticle no Publicador do banco de dados de publicação. Especifique uma das opções de detecção e resolução de conflitos para o registro lógico:
Para detectar e resolver conflitos que ocorrem dentro das linhas relacionadas no registro lógico, especifique um valor de true para @logical_record_level_conflict_detection e @logical_record_level_conflict_resolution.
Para usar a detecção e resolução de conflitos padrão de linha ou coluna, especifique o valor de false para @logical_record_level_conflict_detection e @logical_record_level_conflict_resolution, que é o padrão.
Repita a Etapa 2 para cada artigo que integrará o registro lógico. É preciso usar a mesma opção de detecção e resolução de conflitos para cada artigo no registro lógico. Para obter mais informações, consulte Detectando e resolvendo conflitos em registros lógicos.
No Publicador do banco de dados de publicação, execute sp_addmergefilter. Especifique @publication; o nome do artigo na relação para @article; o nome do segundo artigo para @join_articlename; o nome da relação para @filtername; a cláusula que define a relação entre os dois artigos para @join_filterclause; o tipo de junção para @join_unique_key e um dos valores a seguir para @filter_type:
2 - Define uma relação lógica.
3 - Define uma relação lógica com um filtro de junção.
Observação Se um filtro de junção não for usado, a direção da relação entre os dois artigos não será importante.
Repita a Etapa 2 para cada relação de registro lógico remanescente na publicação.
Para alterar a detecção e resolução de conflito para registros lógicos
Para detectar e resolver conflitos que ocorrem dentro de linhas relacionadas no registro lógico:
No Publicador do banco de dados de publicação, execute sp_changemergearticle. Especifique um valor de logical_record_level_conflict_detection para @property, e um valor de true para @value. Especifique um valor de 1 para @force_invalidate_snapshot e @force_reinit_subscription.
No Publicador do banco de dados de publicação, execute sp_changemergearticle. Especifique um valor de logical_record_level_conflict_resolution para @property, e um valor de true para @value. Especifique um valor de 1 para @force_invalidate_snapshot e @force_reinit_subscription.
Para usar a detecção e resolução de conflitos padrão em nível de linha ou coluna:
No Publicador do banco de dados de publicação, execute sp_changemergearticle. Especifique um valor de logical_record_level_conflict_detection para @property, e um valor de true para @value. Especifique um valor de 1 para @force_invalidate_snapshot e @force_reinit_subscription.
No Publicador do banco de dados de publicação, execute sp_changemergearticle. Especifique um valor de logical_record_level_conflict_resolution para @property, e um valor de false para @value. Especifique um valor de 1 para @force_invalidate_snapshot e @force_reinit_subscription.
Para remover uma relação de registro lógico.
No Publicador do banco de dados de publicação, execute a consulta a seguir para retornar informações sobre todos as relações de registro lógicos definidos para a publicação especificada:
SELECT f.* FROM sysmergesubsetfilters AS f INNER JOIN sysmergepublications AS p ON f.pubid = p.pubid WHERE p.[name] = @publication;
Anote o nome da relação de registro lógico sendo removido da coluna filtername no conjunto de resultados.
Observação Essa consulta retorna as mesmas informações de sp_helpmergefilter; no entanto, esse procedimento armazenado de sistema retorna apenas informações sobre relações de registro lógico que são também filtros de junção.
No Publicador do banco de dados de publicação, execute sp_dropmergefilter. Especifique @publication, o nome de um dos artigos da relação para @article, e o nome da relação da Etapa 1 para @filtername.
Exemplo (Transact-SQL)
Esse exemplo permite partições pré-computadas em uma publicação existente e cria um registro lógico que inclui os dois novos artigos para as tabelas SalesOrderHeader e 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
[Top]
Usando o RMO (Replication Management Objects)
Observação |
---|
A replicação de mesclagem lhe permite também especificar que os conflitos sejam rastreados e resolvidos em nível de registro lógico, mas essas opções não podem ser definidas usando-se RMO. |
Para definir uma relação de registro lógico sem filtro de junção associado
Crie uma conexão com o Publicador usando a classe ServerConnection.
Crie uma instância da classe MergePublication, defina Name e propriedades DatabaseName para a publicação, e defina a propriedade ConnectionContext para a conexão criada no etapa 1.
Chame o método LoadProperties para obter as propriedades do objeto. Se esse método retornar false, as propriedades de publicação na etapa 2 foram definidas incorretamente ou a publicação não existe.
Se a propriedade PartitionGroupsOptionfor definida como False, defina-a para True.
Se os artigos que farão parte do registro lógico não existem, crie uma instância de classe MergeArticle e defina as seguintes propriedades:
Nome do artigo para Name.
Nome da publicação para PublicationName.
(Opcional) Se o artigo for filtrado horizontalmente, especifique a cláusula do filtro da linha para a propriedade FilterClause. Use essa propriedade para especificar um filtro de linha estático ou com parâmetros. Para obter mais informações, consulte Filtros de linha com parâmetros.
Para obter mais informações, consulte Defina um Artigo.
Chame o método Create.
Repita a etapa 5 e 6 para cada artigo que integra o registro lógico.
Crie uma instância da classe MergeJoinFilter para definir a relação de registro lógica entre artigos. Em seguida, defina as seguintes propriedades:
O nome do artigo filho na relação de registro lógico para a propriedade ArticleName.
O nome do artigo pai existente na relação de registro lógico para a propriedade JoinArticleName.
Um nome para a relação de registro lógico para a propriedade FilterName.
A expressão que define a relação para a propriedade JoinFilterClause.
O valor de LogicalRecordLink para a propriedade FilterTypes. Se a relação de registro lógica também for um filtro de junção, especifique um valor de JoinFilterAndLogicalRecordLink para essa propriedade. Para obter mais informações, consulte Agrupar alterações a linhas relacionadas com registros lógicos.
Chame o método AddMergeJoinFilter no objeto que representa o artigo filho na relação. Passe o objeto MergeJoinFilter da etapa 8 para definir a relação.
Repita as etapas 8 e 9 para cada relação de registro lógico remanescente na publicação.
Exemplo (RMO)
Esse exemplo cria um registro lógico que inclui os dois novos artigos para as tabelas SalesOrderHeader e SalesOrderDetail.
// Define the Publisher and publication names.
string publisherName = publisherInstance;
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorks2012";
// Specify article names.
string articleName1 = "SalesOrderHeader";
string articleName2 = "SalesOrderDetail";
// Specify logical record information.
string lrName = "SalesOrderHeader_SalesOrderDetail";
string lrClause = "[SalesOrderHeader].[SalesOrderID] = "
+ "[SalesOrderDetail].[SalesOrderID]";
string schema = "Sales";
MergeArticle article1 = new MergeArticle();
MergeArticle article2 = new MergeArticle();
MergeJoinFilter lr = new MergeJoinFilter();
MergePublication publication = new MergePublication();
// Create a connection to the Publisher.
ServerConnection conn = new ServerConnection(publisherName);
try
{
// Connect to the Publisher.
conn.Connect();
// Verify that the publication uses precomputed partitions.
publication.Name = publicationName;
publication.DatabaseName = publicationDbName;
publication.ConnectionContext = conn;
// If we can't get the properties for this merge publication, then throw an application exception.
if (publication.LoadProperties())
{
// If precomputed partitions is disabled, enable it.
if (publication.PartitionGroupsOption == PartitionGroupsOption.False)
{
publication.PartitionGroupsOption = PartitionGroupsOption.True;
}
}
else
{
throw new ApplicationException(String.Format(
"Settings could not be retrieved for the publication. " +
"Ensure that the publication {0} exists on {1}.",
publicationName, publisherName));
}
// Set the required properties for the PurchaseOrderHeader article.
article1.ConnectionContext = conn;
article1.Name = articleName1;
article1.DatabaseName = publicationDbName;
article1.SourceObjectName = articleName1;
article1.SourceObjectOwner = schema;
article1.PublicationName = publicationName;
article1.Type = ArticleOptions.TableBased;
// Set the required properties for the SalesOrderDetail article.
article2.ConnectionContext = conn;
article2.Name = articleName2;
article2.DatabaseName = publicationDbName;
article2.SourceObjectName = articleName2;
article2.SourceObjectOwner = schema;
article2.PublicationName = publicationName;
article2.Type = ArticleOptions.TableBased;
if (!article1.IsExistingObject) article1.Create();
if (!article2.IsExistingObject) article2.Create();
// Define a logical record relationship between
// PurchaseOrderHeader and PurchaseOrderDetail.
// Parent article.
lr.JoinArticleName = articleName1;
// Child article.
lr.ArticleName = articleName2;
lr.FilterName = lrName;
lr.JoinUniqueKey = true;
lr.FilterTypes = FilterTypes.LogicalRecordLink;
lr.JoinFilterClause = lrClause;
// Add the logical record definition to the parent article.
article1.AddMergeJoinFilter(lr);
}
catch (Exception ex)
{
// Do error handling here and rollback the transaction.
throw new ApplicationException(
"The filtered articles could not be created", ex);
}
finally
{
conn.Disconnect();
}
' Define the Publisher and publication names.
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2012"
' Specify article names.
Dim articleName1 As String = "SalesOrderHeader"
Dim articleName2 As String = "SalesOrderDetail"
' Specify logical record information.
Dim lrName As String = "SalesOrderHeader_SalesOrderDetail"
Dim lrClause As String = "[SalesOrderHeader].[SalesOrderID] = " _
& "[SalesOrderDetail].[SalesOrderID]"
Dim schema As String = "Sales"
Dim article1 As MergeArticle = New MergeArticle()
Dim article2 As MergeArticle = New MergeArticle()
Dim lr As MergeJoinFilter = New MergeJoinFilter()
Dim publication As MergePublication = New MergePublication()
' Create a connection to the Publisher.
Dim conn As ServerConnection = New ServerConnection(publisherName)
Try
' Connect to the Publisher.
conn.Connect()
' Verify that the publication uses precomputed partitions.
publication.Name = publicationName
publication.DatabaseName = publicationDbName
publication.ConnectionContext = conn
' If we can't get the properties for this merge publication, then throw an application exception.
If publication.LoadProperties() Then
' If precomputed partitions is disabled, enable it.
If publication.PartitionGroupsOption = PartitionGroupsOption.False Then
publication.PartitionGroupsOption = PartitionGroupsOption.True
End If
Else
Throw New ApplicationException(String.Format( _
"Settings could not be retrieved for the publication. " _
& "Ensure that the publication {0} exists on {1}.", _
publicationName, publisherName))
End If
' Set the required properties for the SalesOrderHeader article.
article1.ConnectionContext = conn
article1.Name = articleName1
article1.DatabaseName = publicationDbName
article1.SourceObjectName = articleName1
article1.SourceObjectOwner = schema
article1.PublicationName = publicationName
article1.Type = ArticleOptions.TableBased
' Set the required properties for the SalesOrderDetail article.
article2.ConnectionContext = conn
article2.Name = articleName2
article2.DatabaseName = publicationDbName
article2.SourceObjectName = articleName2
article2.SourceObjectOwner = schema
article2.PublicationName = publicationName
article2.Type = ArticleOptions.TableBased
If Not article1.IsExistingObject Then
article1.Create()
End If
If Not article2.IsExistingObject Then
article2.Create()
End If
' Define a logical record relationship between
' SalesOrderHeader and SalesOrderDetail.
' Parent article.
lr.JoinArticleName = articleName1
' Child article.
lr.ArticleName = articleName2
lr.FilterName = lrName
lr.JoinUniqueKey = True
lr.FilterTypes = FilterTypes.LogicalRecordLink
lr.JoinFilterClause = lrClause
' Add the logical record definition to the parent article.
article1.AddMergeJoinFilter(lr)
Catch ex As Exception
' Do error handling here and rollback the transaction.
Throw New ApplicationException( _
"The filtered articles could not be created", ex)
Finally
conn.Disconnect()
End Try
[Top]
Consulte também
Conceitos
Definir e modificar um filtro de junção entre artigos de mesclagem
Definir e modificar um filtro de linha com parâmetros para um artigo de mesclagem
Definir e modificar um filtro de linha estático
Agrupar alterações a linhas relacionadas com registros lógicos
Definir uma relação de registro lógico entre artigos da tabela de mesclagem
Otimizar o desempenho de filtro parametrizado com partições pré-computadas
Agrupar alterações a linhas relacionadas com registros lógicos