Définir une relation d'enregistrement logique entre des articles de table de fusion
Cette rubrique explique comment définir une relation d'enregistrement logique entre des articles de table de fusion dans SQL Server 2012 à l'aide de SQL Server Management Studio, Transact-SQL ou d'objets RMO (Replication Management Objects).
La réplication de fusion vous permet de définir une relation entre des lignes connexes dans des tables distinctes. Ces lignes peuvent alors être traitées comme une unité transactionnelle au cours de la synchronisation. Un enregistrement logique peut être défini entre deux articles qu'ils aient ou non une relation de filtre de jointure. Pour plus d'informations, consultez Regrouper les modifications apportées à des lignes connexes à l'aide d'enregistrements logiques.
[!REMARQUE]
Cette fonctionnalité sera supprimée dans une prochaine version de Microsoft SQL Server. Évitez d'utiliser cette fonctionnalité dans de nouveaux travaux de développement et prévoyez de modifier les applications qui utilisent actuellement cette fonctionnalité.
Dans cette rubrique
Avant de commencer :
Limitations et restrictions
Pour définir une relation d'enregistrement logique entre des articles de table de fusion à l'aide de :
SQL Server Management Studio
Transact-SQL
Objets RMO (Replication Management Objects)
Avant de commencer
Limitations et restrictions
- Si vous ajoutez, modifiez ou supprimez un enregistrement logique après que les abonnements à la publication aient été initialisés, vous devez générer un nouvel instantané et réinitialiser tous les abonnements après avoir effectué la modification. Pour plus d'informations sur les conditions requises pour les modifications des propriétés, consultez Modifier les propriétés des publications et des articles.
[Top]
Utilisation de SQL Server Management Studio
Définissez des enregistrements logiques dans la boîte de dialogue Ajouter une jointure, qui est disponible dans l'Assistant Nouvelle publication et dans la boîte de dialogue Propriétés de la publication - <publication>. Pour plus d'informations sur l'utilisation de cet Assistant et sur l'accès à cette boîte de dialogue, consultez Créer une publication et Afficher et modifier les propriétés d'une publication.
Les enregistrements logiques peuvent être définis dans la boîte de dialogue Ajouter une jointure seulement s'ils sont appliqués à un filtre de jointure dans une publication de fusion, et si la publication satisfait aux conditions requises pour l'utilisation de partitions précalculées. Pour définir des enregistrements logiques qui ne sont pas appliqués à des filtres de jointure et pour définir la détection et la résolution des conflits au niveau des enregistrements logiques, vous devez utiliser des procédures stockées.
Pour définir une relation d'enregistrement logique
Sur la page Filtrer les lignes de la table de l'Assistant Nouvelle publication ou sur la page Filtrer les lignes de la boîte de dialogue Propriétés de la publication - <publication>, sélectionnez un filtre de lignes dans le volet Tables filtrées.
Une relation d'enregistrement logique est associée à un filtre de jointure, qui étend un filtre de lignes. Vous devez donc définir un filtre de lignes avant de pouvoir étendre le filtre avec une jointure et appliquer une relation d'enregistrement logique. Après avoir défini un filtre de jointure, vous pouvez l'étendre avec un autre filtre de jointure. Pour plus d'informations sur la définition de filtres de jointure, consultez Définir et modifier un filtre de jointure entre des articles de fusion.
Cliquez sur Ajouter, puis sur Ajouter une jointure pour étendre le filtre sélectionné.
Définissez un filtre de jointure dans la boîte de dialogue Ajouter une jointure, puis activez la case à cocher Enregistrement logique.
Si vous êtes dans la boîte de dialogue Propriétés de la publication - <publication>, cliquez sur OK pour enregistrer et fermer la boîte de dialogue.
Pour supprimer une relation d'enregistrement logique
Supprimer seulement la relation d'enregistrement logique ou supprimer la relation d'enregistrement logique et le filtre de jointure qui y est associé.
Pour supprimer seulement la relation d'enregistrement logique :
Sur la page Filtrer les lignes de l'Assistant Nouvelle publication ou sur la page Filtrer les lignes de la boîte de dialogue Propriétés de la publication - <publication>, sélectionnez le filtre de jointure associé à la relation d'enregistrement logique dans le volet Tables filtrées, puis cliquez sur Modifier.
Dans la boîte de dialogue Modifier une jointure, désactivez la case à cocher Enregistrement logique.
Cliquez sur OK.
Pour supprimer la relation d'enregistrement logique et le filtre de jointure qui y est associé :
- Sur la page Filtrer les lignes de l'Assistant Nouvelle publication ou de la boîte de dialogue Propriétés de la publication - <publication>, sélectionnez un filtre dans le volet Tables filtrées, puis cliquez sur Supprimer. Si le filtre de jointure que vous supprimez est lui-même étendu par d'autres jointures, ces jointures seront aussi supprimées.
[Top]
Utilisation de Transact-SQL
Vous pouvez spécifier par programme des relations d'enregistrements logiques entre des articles en utilisant des procédures stockées de réplication.
Pour définir une relation d'enregistrements logiques sans filtre de jointure associé
Si la publication contient des articles filtrés, exécutez sp_helpmergepublication et notez la valeur de use_partition_groups dans le jeu de résultats.
Si la valeur est 1, les partitions précalculées sont déjà utilisées.
Si la valeur est 0, exécutez sp_changemergepublication au niveau du serveur de publication dans la base de données de publication. Affectez la valeur use_partition_groups à @property et la valeur true à @value.
[!REMARQUE]
Si la publication ne prend pas en charge les partitions précalculées, les enregistrements logiques ne peuvent pas être utilisés. Pour plus d'informations, consultez la section « Conditions requises à l'utilisation des partitions précalculées » dans la rubrique Optimiser les performances des filtres paramétrés avec des partitions précalculées.
Si la valeur est NULL, l'Agent d'instantané doit être exécuté pour générer l'instantané initial de la publication.
Si les articles qui constitueront l'enregistrement logique n'existent pas, exécutez sp_addmergearticle au niveau du serveur de publication dans la base de données de publication. Spécifiez l'une des options de détection et de résolution des conflits suivantes pour l'enregistrement logique :
Pour détecter et résoudre les conflits qui se produisent dans des lignes connexes de l'enregistrement logique, affectez la valeur true à @logical_record_level_conflict_detection et @logical_record_level_conflict_resolution.
Pour utiliser la détection et la résolution standard des conflits au niveau des lignes ou des colonnes, affectez la valeur false à @logical_record_level_conflict_detection et @logical_record_level_conflict_resolution, qui est la valeur par défaut.
Répétez l'étape 2 pour chaque article qui constituera l'enregistrement logique. Vous devez utiliser la même option de détection et de résolution des conflits pour chaque article de l'enregistrement logique. Pour plus d'informations, consultez Détection et résolution des conflits dans les enregistrements logiques.
Dans la base de données de publication sur le serveur de publication, exécutez sp_addmergefilter. Spécifiez @publication, le nom d'un article de la relation pour @article, le nom du deuxième article pour @join_articlename, le nom de la relation pour @filtername, une clause qui définit la relation entre les deux articles pour @join_filterclause, le type de jointure pour @join_unique_key et affectez l'une des valeurs suivantes à @filter_type :
2 - définit une relation logique.
3 - définit une relation logique avec un filtre de jointure.
[!REMARQUE]
Si aucun filtre de jointure n'est pas utilisé, la direction de la relation entre les deux articles n'est pas importante.
Répétez l'étape 2 pour chaque relation d'enregistrement logique restante dans la publication.
Pour modifier la détection et la résolution des conflits pour les enregistrements logiques
Pour détecter et résoudre les conflits qui se produisent dans des lignes connexes de l'enregistrement logique :
Dans la base de données de publication sur le serveur de publication, exécutez sp_changemergearticle. Affectez la valeur logical_record_level_conflict_detection à @property et la valeur true à @value. Affectez la valeur 1 à @force_invalidate_snapshot et @force_reinit_subscription.
Dans la base de données de publication sur le serveur de publication, exécutez sp_changemergearticle. Affectez la valeur logical_record_level_conflict_resolution à @property et la valeur true à @value. Affectez la valeur 1 à @force_invalidate_snapshot et @force_reinit_subscription.
Pour utiliser la détection et la résolution standard des conflits au niveau des lignes ou des colonnes :
Dans la base de données de publication sur le serveur de publication, exécutez sp_changemergearticle. Affectez la valeur logical_record_level_conflict_detection à @property et la valeur false à @value. Affectez la valeur 1 à @force_invalidate_snapshot et @force_reinit_subscription.
Dans la base de données de publication sur le serveur de publication, exécutez sp_changemergearticle. Affectez la valeur logical_record_level_conflict_resolution à @property et la valeur false à @value. Affectez la valeur 1 à @force_invalidate_snapshot et @force_reinit_subscription.
Pour supprimer une relation d'enregistrements logiques
Dans la base de données de publication sur le serveur de publication, exécutez la requête suivante afin que des informations sur toutes les relations d'enregistrements logiques définies pour la publication spécifiée soient retournées :
SELECT f.* FROM sysmergesubsetfilters AS f INNER JOIN sysmergepublications AS p ON f.pubid = p.pubid WHERE p.[name] = @publication;
Notez le nom de la relation d'enregistrements logiques en cours de suppression dans la colonne filtername du jeu de résultats.
[!REMARQUE]
Cette requête retourne les mêmes informations que sp_helpmergefilterToutefois, cette procédure stockée système retourne seulement des informations sur les relations d'enregistrements logiques qui sont également des filtres de jointure.
Dans la base de données de publication sur le serveur de publication, exécutez sp_dropmergefilter. Spécifiez @publication, le nom de l'un des articles de la relation pour @article et le nom de la relation de l'étape 1 pour @filtername.
Exemple (Transact-SQL)
Cet exemple active les partitions précalculées sur une publication existante et crée un enregistrement logique qui comprend les deux nouveaux articles des tables SalesOrderHeader et 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]
Utilisation d'objets RMO (Replication Management Objects)
[!REMARQUE]
La réplication de fusion vous permet de spécifier que les conflits soient suivis et résolus au niveau des enregistrements logiques, mais ces options ne peuvent pas être définies à l'aide des objets RMO.
Pour définir une relation d'enregistrement logique sans filtre de jointure associé
Créez une connexion au serveur de publication en utilisant la classe ServerConnection.
Créez une instance de la classe MergePublication, définissez les propriétés Name et DatabaseName pour la publication et définissez la propriété ConnectionContext sur la connexion créée à l'étape 1.
Appelez la méthode LoadProperties pour obtenir les propriétés de l'objet. Si cette méthode retourne false, soit les propriétés de la publication ont été définies de manière incorrecte à l'étape 2, soit la publication n'existe pas.
Si la propriété PartitionGroupsOption a la valeur False, affectez-lui la valeur True.
Si les articles devant inclure l'enregistrement logique n'existent pas, créez une instance de la classe MergeArticle et définissez les propriétés suivantes :
Le nom de l'article pour Name.
Le nom de la publication pour PublicationName.
(Facultatif) Si l'article est filtré horizontalement, spécifiez la clause de filtre de lignes pour la propriété FilterClause. Utilisez cette propriété pour spécifier un filtre de lignes statique ou paramétrable. Pour plus d'informations, consultez Filtres de lignes paramétrés.
Pour plus d'informations, consultez Définir un article.
Appelez la méthode Create.
Répétez les étapes 5 et 6 pour chaque article qui comprend l'enregistrement logique.
Créez une instance de la classe MergeJoinFilter pour définir la relation d'enregistrement logique entre les articles. Définissez ensuite les propriétés suivantes :
Le nom de l'article enfant dans la relation d'enregistrement logique pour la propriété ArticleName.
Le nom de l'article parent existant dans la relation d'enregistrement logique pour la propriété JoinArticleName.
Un nom pour la relation d'enregistrement logique pour la propriété FilterName.
L'expression qui définit la relation pour la propriété JoinFilterClause.
Une valeur de LogicalRecordLink pour la propriété FilterTypes. Si la relation d'enregistrement logique correspond également à un filtre de jointure, spécifiez une valeur de JoinFilterAndLogicalRecordLink pour cette propriété. Pour plus d'informations, consultez Regrouper les modifications apportées à des lignes connexes à l'aide d'enregistrements logiques.
Appelez la méthode AddMergeJoinFilter sur l'objet qui représente l'article enfant dans la relation. Passez l'objet MergeJoinFilter créé à l'étape 8 pour définir la relation.
Répétez les étapes 8 et 9 pour chaque relation d'enregistrement logique restante dans la publication.
Exemple (RMO)
Cet exemple crée un enregistrement logique qui comprend les deux nouveaux articles pour les tables SalesOrderHeader et 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]
Voir aussi
Concepts
Définir et modifier un filtre de jointure entre des articles de fusion
Définir et modifier un filtre de lignes paramétrable pour un article de fusion
Définir et modifier un filtre de lignes statiques
Regrouper les modifications apportées à des lignes connexes à l'aide d'enregistrements logiques
Définir une relation d'enregistrement logique entre des articles de table de fusion
Optimiser les performances des filtres paramétrés avec des partitions précalculées
Regrouper les modifications apportées à des lignes connexes à l'aide d'enregistrements logiques