Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Van toepassing op:SQL Server
Dit onderwerp beschrijft hoe een logische recordrelatie tussen merge-tabel artikelen in SQL Server gedefinieerd kan worden door gebruik te maken van SQL Server Management Studio, Transact-SQL of Replication Management Objects (RMO).
Merge replicatie stelt je in staat een relatie te definiëren tussen gerelateerde rijen in verschillende tabellen. Deze rijen kunnen vervolgens als transactionele eenheid worden verwerkt tijdens de synchronisatie. Een logisch record kan worden gedefinieerd tussen twee artikelen, ongeacht of ze een joinfilterrelatie hebben of niet. Zie Groepswijzigingen in gerelateerde rijen met logische records voor meer informatie.
Note
Deze functie wordt verwijderd in een toekomstige versie van SQL Server. Vermijd het gebruik van deze functie in nieuwe ontwikkelwerkzaamheden en plan om toepassingen te wijzigen die momenteel gebruikmaken van deze functie.
Beperkingen en beperkingen
- Als je een logisch record toevoegt, apast of verwijdert nadat de abonnementen op de publicatie zijn geïnitialiseerd, moet je een nieuwe snapshot genereren en alle abonnementen opnieuw initialiseren na de wijziging. Voor meer informatie over vereisten voor wijzigingen in eigenschappen, raadpleeg Publicatie- en artikeleigenschappen wijzigen.
SQL Server Management Studio gebruiken
Definieer logische records in het dialoogvenster Voeg Join , dat beschikbaar is in de New Publication Wizard en het dialoogvenster Publicatie-eigenschappen - <Publicatie> . Zie Een publicatie maken en publicatie-eigenschappen weergeven en wijzigen voor meer informatie over het gebruik van de wizard en het openen van het dialoogvenster.
Logische records kunnen alleen worden gedefinieerd in het dialoogvenster Add Join als ze worden toegepast op een joinfilter in een mergepublicatie, en de publicatie voldoet aan de eisen voor het gebruik van vooraf berekende partities. Om logische records te definiëren die niet worden toegepast op joinfilters en om conflictdetectie en -oplossing op het niveau van logische records in te stellen, moet je opgeslagen procedures gebruiken.
Om een logische recordrelatie te definiëren
Selecteer op de pagina Filtertabelrijen van de Nieuwe Publicatiewizard of de pagina Filterrijen van het dialoogvenster Publicatie-eigenschappen - <Publicatie> een rijfilter in het Filterde Tabellen-paneel .
Een logische recordrelatie is gekoppeld aan een joinfilter, dat een rijfilter uitbreidt. Daarom moet je een rijfilter definiëren voordat je het filter kunt uitbreiden met een join en een logische recordrelatie kunt toepassen. Nadat één joinfilter is gedefinieerd, kun je dit joinfilter uitbreiden met een ander joinfilter. Raadpleeg Joinfilter tussen merge-artikelen definiëren en wijzigen voor meer informatie over het definiëren van joinfilters.
Klik op Toevoegen en vervolgens op Voeg Aansluiten om het geselecteerde filter uit te breiden.
Definieer een join-filter in het dialoogvenster Join toevoegen en selecteer vervolgens het selectievakje Logical Record.
Als u zich in het dialoogvenster Publicatie-eigenschappen - <Publicatie> bevindt, klikt u op OK om het dialoogvenster op te slaan en te sluiten.
Om een logische recordrelatie te verwijderen
Verwijder alleen de logische recordrelatie of verwijder de logische recordrelatie en het bijbehorende joinfilter.
Om alleen de logische recordrelatie te verwijderen:
Op de pagina Filterrijen van de Nieuwe Publicatiewizard of de pagina Filterrijen van het dialoogvenster Publicatie Eigenschappen - <Publicatie> , selecteer je het joinfilter dat is gekoppeld aan de logische recordrelatie in het paneel Gefilterde Tabellen en klik vervolgens op Bewerken.
In het dialoogvenster 'Samenvoegen bewerken ' verwijdert u het selectievakje Logisch Record.
Kies OK.
Om de logische recordrelatie en joinfilter die eraan gekoppeld zijn te verwijderen:
- Op de pagina Filterrijen van de Nieuwe Publicatiewizard of het venster Publicatie-eigenschappen - <Publicatie> selecteer je een filter in het venster Gefilterde Tabellen en klik je vervolgens op Verwijderen. Als het joinfilter dat je verwijdert zelf wordt uitgebreid met andere joins, worden die joins ook verwijderd.
Transact-SQL gebruiken
Je kunt programmatisch logische recordrelaties tussen artikelen specificeren met replicatie-opgeslagen procedures.
Om een logische recordrelatie te definiëren zonder een bijbehorende join-filter
Als de publicatie artikelen bevat die gefilterd zijn, voer sp_helpmergepublication uit en noteer de waarde van use_partition_groups in de resultaatset.
Als de waarde 1 is, worden vooraf berekende partities al gebruikt.
Als de waarde 0 is, voer dan sp_changemergepublication uit op de Publisher in de publicatiedatabase. Geef een waarde van use_partition_groups op voor @property en een waarde van true voor @value.
Note
Als de publicatie geen vooraf berekende partities ondersteunt, kunnen logische records niet worden gebruikt. Voor meer informatie, zie Vereisten voor het gebruik van vooraf berekende partities in het onderwerp Optimaliseer de prestaties van geparametriseerde filters met vooraf berekende partities.
Als de waarde NULL is, moet de Snapshot Agent worden uitgevoerd om de initiële snapshot voor de publicatie te genereren.
Als de artikelen die het logische record zullen vormen niet bestaan, voer sp_addmergearticle dan uit op de Publisher in de publicatiedatabase. Specificeer een van de volgende opties voor conflictdetectie en -oplossing voor het logische record:
Om conflicten binnen gerelateerde rijen in het logische record te detecteren en op te lossen, specificeer je een waarde van waar voor @logical_record_level_conflict_detection en @logical_record_level_conflict_resolution.
Om de standaard rij- of kolomniveau conflictdetectie en -oplossing te gebruiken, specificeer je een waarde van false voor @logical_record_level_conflict_detection en @logical_record_level_conflict_resolution, wat de standaard is.
Herhaal stap 2 voor elk artikel dat het logische verslag zal vormen. Je moet voor elk artikel dezelfde optie voor conflictdetectie en -oplossing in het logische record gebruiken. Zie Conflicten in logische records detecteren en oplossen voor meer informatie.
Voer bij de uitgever in de publicatiedatabase sp_addmergefilter uit. Specificeer @publication, de naam van één lidwoord in de relatie voor @article, de naam van het tweede artikel voor @join_articlename, een naam voor de relatie voor @filtername, een clausule die de relatie tussen de twee lidwoorden voor @join_filterclause definieert, het type join voor @join_unique_key en een van de volgende waarden voor @filter_type:
2 - Definieert een logische relatie.
3 - Definieert een logische relatie met een joinfilter.
Note
Als er geen joinfilter wordt gebruikt, is de richting van de relatie tussen de twee artikelen niet belangrijk.
Herhaal stap 2 voor elke resterende logische recordrelatie in de publicatie.
Het wijzigen van conflictdetectie en -oplossing voor logische records
Om conflicten te detecteren en op te lossen die voorkomen binnen gerelateerde rijen in het logische record:
Voer sp_changemergearticle uit op de publicatiedatabase bij de Publisher. Geef voor @property een waarde op van logical_record_level_conflict_detection en voor @value een waarde van true. Geef een waarde van 1 aan voor @force_invalidate_snapshot en @force_reinit_subscription.
Voer sp_changemergearticle uit op de publicatiedatabase bij de Publisher. Geef een waarde van logical_record_level_conflict_resolution op voor @property en een waarde van true voor @value. Geef een waarde van 1 aan voor @force_invalidate_snapshot en @force_reinit_subscription.
Om de standaard rij- of kolomniveau conflictdetectie en -oplossing te gebruiken:
Voer sp_changemergearticle uit op de publicatiedatabase bij de Publisher. Specificeer een waarde van logical_record_level_conflict_detection voor @property en een waarde van false voor @value. Geef een waarde van 1 aan voor @force_invalidate_snapshot en @force_reinit_subscription.
Voer sp_changemergearticle uit op de publicatiedatabase bij de Publisher. Specificeer een waarde van logical_record_level_conflict_resolution voor @property en een waarde van false voor @value. Geef een waarde van 1 aan voor @force_invalidate_snapshot en @force_reinit_subscription.
Om een logische recordrelatie te verwijderen
Voer bij de Publisher in de publicatiedatabase de volgende zoekopdracht uit om informatie terug te geven over alle logische recordrelaties die voor de gespecificeerde publicatie zijn gedefinieerd:
SELECT f.* FROM sysmergesubsetfilters AS f INNER JOIN sysmergepublications AS p ON f.pubid = p.pubid WHERE p.[name] = @publication;Let op dat de naam van de logische recordrelatie wordt verwijderd in de filternaamkolom in de resultaatset.
Note
Deze zoekopdracht geeft dezelfde informatie als sp_helpmergefilter; Deze systeemstored procedure geeft echter alleen informatie terug over logische recordrelaties die ook joinfilters zijn.
Voer sp_dropmergefilter uit op de Publisher in de publicatiedatabase. Specificeer @publication, de naam van een van de artikelen in de relatie voor @article, en de naam van de relatie uit stap 1 voor @filtername.
Voorbeeld (Transact-SQL)
Dit voorbeeld maakt vooraf berekende partitities mogelijk op een bestaande publicatie en creëert een logisch record bestaande uit de twee nieuwe artikelen voor de SalesOrderHeader en SalesOrderDetail tabellen.
-- 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
Replicatiebeheerobjecten (RMO) gebruiken
Note
Merge replicatie stelt je in staat om te specificeren dat conflicten op het niveau van het logische record worden gevolgd en opgelost, maar deze opties kunnen niet worden ingesteld met RMO.
Om een logische recordrelatie te definiëren zonder een bijbehorende join-filter
Maak een verbinding met publisher met behulp van de ServerConnection klasse.
Maak een instantie van de MergePublication klasse aan, stel de Name en DatabaseName eigenschappen in voor de publicatie, en stel de ConnectionContext eigenschap in op de verbinding die in stap 1 is gemaakt.
Roep de LoadProperties methode aan om de eigenschappen van het object op te halen. Als deze methode onwaarretourneert, zijn de publicatie-eigenschappen in stap 2 onjuist gedefinieerd of bestaat de publicatie niet.
Als de PartitionGroupsOption eigenschap op is gezet False, zet deze dan op True.
Als de artikelen die het logische record moeten vormen niet bestaan, maak dan een instantie van de MergeArticle klasse aan en stel de volgende eigenschappen in:
De naam van het artikel voor Name.
De naam van de publicatie voor PublicationName.
(Optioneel) Als het artikel horizontaal gefilterd is, specificeer dan de rijfilterclausule voor de FilterClause eigenschap. Gebruik deze eigenschap om een statisch of geparametriseerd rijfilter te specificeren. Zie Geparameteriseerde rijfiltersvoor meer informatie.
Zie Een artikel definiëren voor meer informatie.
Roep de Create methode aan.
Herhaal stappen 5 en 6 voor elk artikel dat het logische record vormt.
Maak een instantie van de MergeJoinFilter klasse aan om de logische recordrelatie tussen artikelen te definiëren. Stel vervolgens de volgende eigenschappen in:
De naam van het kindartikel in de logische recordrelatie voor de ArticleName eigenschap.
De naam van het bestaande, bovenliggende artikel in de logische recordrelatie voor de JoinArticleName eigenschap.
Een naam voor de logische recordrelatie voor het FilterName eigendom.
De uitdrukking die de relatie voor de JoinFilterClause eigenschap definieert.
Een waarde van LogicalRecordLink voor het FilterTypes pand. Als de logische recordrelatie ook een joinfilter is, specificeer dan een waarde van JoinFilterAndLogicalRecordLink voor deze eigenschap. Zie Groepswijzigingen in gerelateerde rijen met logische records voor meer informatie.
Roep de AddMergeJoinFilter methode aan op het object dat het kindartikel in de relatie vertegenwoordigt. Geef het MergeJoinFilter object van stap 8 door om de relatie te definiëren.
Herhaal stappen 8 en 9 voor elke resterende logische recordrelatie in de publicatie.
Voorbeeld (RMO)
Dit voorbeeld creëert een logisch record bestaande uit de twee nieuwe artikelen voor de SalesOrderHeader en SalesOrderDetail tabellen.
// Define the Publisher and publication names.
string publisherName = publisherInstance;
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorks2022";
// 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 = "AdventureWorks2022"
' 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
Verwante onderwerpen
- Een samenvoegfilter definiëren en wijzigen tussen samenvoegartikelen
- Een geparameteriseerd rijfilter definiëren en wijzigen voor een samenvoegartikel
- Een statisch rijfilter definiëren en wijzigen
- Wijzigingen in gerelateerde rijen groeperen met logische records
- Geparametriseerde filters - Optimaliseer voor vooraf berekende partities