Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Dotyczy:SQL Server
Ten temat opisuje, jak zdefiniować logiczne powiązania rekordów między artykułami tabeli scalania w SQL Server, korzystając z SQL Server Management Studio, Transact-SQL lub Replication Management Objects (RMO).
Replikacja scalania pozwala zdefiniować relację między powiązanymi wierszami w różnych tabelach. Te wiersze mogą być następnie przetwarzane jako jednostka transakcyjna podczas synchronizacji. Logiczny rekord można zdefiniować pomiędzy dwoma artykułami, niezależnie od tego, czy mają one relację filtra łączenia, czy nie. Aby uzyskać więcej informacji, zobacz Grupowanie zmian w powiązanych wierszach z rekordami logicznymi.
Uwaga / Notatka
Ta funkcja zostanie usunięta w przyszłej wersji programu SQL Server. Unikaj używania tej funkcji w nowych pracach programistycznych i zaplanuj modyfikowanie aplikacji, które obecnie korzystają z tej funkcji.
Ograniczenia i ograniczenia
- Jeśli dodasz, zmodyfikujesz lub usuniesz zapis logiczny po zainicjowaniu subskrypcji publikacji, musisz wygenerować nowy snapshot i ponownie zainicjować wszystkie subskrypcje po wprowadzeniu zmiany. Więcej informacji o wymaganiach dotyczących zmian właściwości można znaleźć w temacie Zmienianie właściwości publikacji i artykułu.
Korzystanie z programu SQL Server Management Studio
Zdefiniuj logiczne rekordy w oknie dialogowym Dodaj dołącz, które jest dostępne w kreatorze Nowej Publikacji oraz w oknie Właściwości Publikacji - <Publikacja> . Aby uzyskać więcej informacji na temat korzystania z kreatora i uzyskiwania dostępu do okna dialogowego, zobacz Tworzenie publikacji i Wyświetlanie i modyfikowanie właściwości publikacji.
Logiczne rekordy można zdefiniować w oknie dialogowym Add Join tylko wtedy, gdy są stosowane do filtra łączenia w publikacji merge, a publikacja spełnia wymagania dotyczące użycia wstępnie obliczonych partycji. Aby zdefiniować rekordy logiczne, które nie są stosowane do filtrów stowarzyszeń oraz ustawić wykrywanie i rozwiązywanie konfliktów na poziomie rekordów logicznych, należy użyć procedur przechowywanych.
Aby zdefiniować logiczną relację rekordu
Na stronie Filtrowanie wierszy tabeli w Kreatorze nowej publikacji lub na stronie Filtrowanie wierszy w oknie dialogowym Właściwości publikacji — <Publikacja> wybierz filtr wierszy w panelu Filtrowane tabele.
Logiczne powiązanie rekordu jest powiązane z filtrem skojarzenia, który rozszerza filtr wierszowy. Dlatego musisz zdefiniować filtr wierszy, zanim będzie można rozszerzyć go o złączenie i zastosować logiczną relację między rekordami. Po zdefiniowaniu jednego filtra łączenia można go rozszerzyć o inny filtr połączenia. Więcej informacji o definiowaniu filtrów łączenia można znaleźć w artykule Zdefiniuj i zmodyfikuj filtr łączenia między artykułami scalania.
Kliknij Dodaj się, a następnie Dodaj dołącz, aby rozszerzyć wybrany filtr.
Zdefiniuj filtr łączenia w oknie dialogowym Dodaj dołączenie , a następnie zaznacz pole Logiczny rekord.
Jeśli jesteś w oknie dialogowym Właściwości publikacji — <Publikacja>, kliknij przycisk OK, aby zapisać zmiany i zamknąć okno dialogowe.
Usuwanie logicznego powiązania rekordu
Usuń tylko relację logicznego rekordu lub usuń powiązanie logicznego rekordu i powiązany z nią filtr dołączenia.
Aby usunąć tylko relację logicznego rekordu:
Na stronie Filtrowanie wierszy w Kreatorze nowej publikacji lub na stronie Filtrowanie wierszy w oknie dialogowym Właściwości publikacji — <Publikacja> wybierz filtr sprzężenia powiązany z logiczną relacją rekordów w panelu Filtrowane tabele, a następnie kliknij przycisk Edytuj.
W oknie dialogowym Edytuj Dołączenie usuń pole Logiczny rekord.
Kliknij przycisk OK.
Aby usunąć powiązanie logicznego rekordu i filtr łączenia z nim powiązany:
- Na stronie Filtrowanie wierszy w Kreatorze nowej publikacji lub w oknie dialogowym Właściwości publikacji — <Publikacja> wybierz filtr w okienku Filtrowane tabele, a następnie kliknij przycisk Usuń. Jeśli filtr joinów, który usuniesz, sam zostanie rozszerzony o inne joiny, te joiny również zostaną usunięte.
Korzystanie z Transact-SQL
Możesz programowo określić logiczne relacje rekordów między artykułami za pomocą procedur przechowywanych w replikacji.
Aby zdefiniować logiczne powiązanie rekordu bez powiązanego filtra łączenia
Jeśli publikacja zawiera artykuły filtrowane, wykonaj sp_helpmergepublication i zanotuj wartość use_partition_groups w zbiorze wyników.
Jeśli wartość wynosi 1, to już są używane wcześniej obliczone partycje.
Jeśli wartość wynosi 0, uruchom sp_changemergepublication na serwerze Publisher w bazie danych publikacji. Określmy wartość use_partition_groups dla @property oraz wartość true dla @value.
Uwaga / Notatka
Jeśli publikacja nie obsługuje partycji wstępnie obliczonych, nie można używać zapisów logicznych. Więcej informacji można znaleźć w temacie Wymagania dotyczące używania wstępnie obliczonych partycji w sekcji Optymalizacja wydajności filtrowania parametryzowanego przy użyciu wstępnie obliczonych partycji.
Jeśli wartość jest NULL, to Snapshot Agent musi zostać uruchomiony, aby wygenerować początkowy snapshot dla publikacji.
Jeśli artykuły, które będą tworzyć rekord logiczny, nie istnieją, wykonaj sp_addmergearticle u wydawcy w bazie danych publikacji. Określ jedną z następujących opcji wykrywania i rozwiązywania konfliktów dla rekordu logicznego:
Aby wykryć i rozwiązać konflikty występujące w powiązanych wierszach w rekordzie logicznym, określ wartość true dla @logical_record_level_conflict_detection i @logical_record_level_conflict_resolution.
Aby użyć standardowego wykrywania i rozwiązywania konfliktów na poziomie wiersza lub kolumny, należy określić wartość falsz dla @logical_record_level_conflict_detection i @logical_record_level_conflict_resolution, co jest domyślne.
Powtórz krok 2 dla każdego artykułu, który będzie stanowił logiczny zapis. Musisz użyć tej samej opcji wykrywania i rozwiązywania konfliktów dla każdego artykułu w logicznym rekordzie. Aby uzyskać więcej informacji, zobacz Wykrywanie i rozwiązywanie konfliktów w rekordach logicznych.
Na serwerze wydawcy, w bazie danych publikacji, wykonaj sp_addmergefilter. Określ @publication, nazwę jednego artykułu w relacji dla @article, nazwę drugiego artykułu dla @join_articlename, nazwę relacji dla @filtername, klauzulę definiującą relację między dwoma artykułami dla @join_filterclause, typ łączenia dla @join_unique_key oraz jedną z następujących wartości dla @filter_type:
2 - Definiuje zależność logiczną.
3 - Definiuje logiczne powiązanie z filtrem łączenia.
Uwaga / Notatka
Jeśli filtr łączenia nie jest używany, kierunek relacji między dwoma artykułami nie ma znaczenia.
Powtórz krok 2 dla każdej pozostałej relacji między rekordami logicznymi w publikacji.
Zmiana wykrywania i rozstrzygania konfliktów dla rekordów logicznych
Aby wykryć i rozwiązać konflikty występujące w powiązanych wierszach w rekordzie logicznym:
W Publisher w bazie danych publikacji wykonaj sp_changemergearticle. Określ wartość logical_record_level_conflict_detection dla @property oraz wartość true dla @value. Określ wartość 1 dla @force_invalidate_snapshot i @force_reinit_subscription.
W Publisher w bazie danych publikacji wykonaj sp_changemergearticle. Określ wartość logical_record_level_conflict_resolution dla @property oraz wartość true dla @value. Określ wartość 1 dla @force_invalidate_snapshot i @force_reinit_subscription.
Aby użyć standardowego wykrywania i rozwiązywania konfliktów na poziomie wiersza lub kolumny:
W Publisher w bazie danych publikacji wykonaj sp_changemergearticle. Określ wartość logical_record_level_conflict_detection dla @property oraz wartość false dla @value. Określ wartość 1 dla @force_invalidate_snapshot i @force_reinit_subscription.
W Publisher w bazie danych publikacji wykonaj sp_changemergearticle. Określ wartość logical_record_level_conflict_resolution dla @property oraz wartość false dla @value. Określ wartość 1 dla @force_invalidate_snapshot i @force_reinit_subscription.
Aby usunąć logiczne powiązanie rekordu
W Publisher w bazie publikacji wykonaj następujące zapytanie, aby zwrócić informacje o wszystkich logicznych relacjach rekordów zdefiniowanych dla określonej publikacji:
SELECT f.* FROM sysmergesubsetfilters AS f INNER JOIN sysmergepublications AS p ON f.pubid = p.pubid WHERE p.[name] = @publication;Zwróć uwagę na nazwę usuwanej relacji rekordu logicznego w kolumnie filtername w zbiorze wyników.
Uwaga / Notatka
To zapytanie zwraca te same informacje co sp_helpmergefilter; jednak ta procedura przechowywana w systemie zwraca jedynie informacje o logicznym powiązaniach rekordów, które również są filtrami stowarzyszeń.
Na serwerze Publisher w bazie danych publikacji wykonaj sp_dropmergefilter. Określ @publication, nazwę jednego z artykułów w ramach relacji dla @article oraz nazwę relacji z kroku 1 dla @filtername.
Przykład (Transact-SQL)
Ten przykład włącza wstępnie obliczone partycje dla istniejącej publikacji i tworzy rekord logiczny składający się z dwóch nowych artykułów dla tabel SalesOrderHeader i 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
Korzystanie z obiektów zarządzania replikacją (RMO)
Uwaga / Notatka
Replikacja scalania umożliwia określenie, aby konflikty były śledzone i rozwiązywane na poziomie rekordu logicznego, ale tych opcji nie można ustawić za pomocą RMO.
Aby zdefiniować logiczne powiązanie rekordu bez powiązanego filtra łączenia
Utwórz połączenie z programem Publisher przy użyciu klasy ServerConnection.
Utwórz instancję klasy MergePublication, ustaw właściwości Name i DatabaseName dla publikacji oraz ustaw właściwość ConnectionContext na połączenie utworzone w kroku 1.
Wywołaj metodę LoadProperties, aby uzyskać właściwości obiektu. Jeśli ta metoda zwraca false, właściwości publikacji w kroku 2 zostały niepoprawnie zdefiniowane lub publikacja nie istnieje.
Jeśli właściwość PartitionGroupsOption jest ustawiona na False, ustaw ją na True.
Jeśli artykuły tworzące rekord logiczny nie istnieją, stwórz instancję MergeArticle klasy i ustaw następujące właściwości:
Nazwa artykułu dla Name.
Nazwa publikacji dla PublicationName.
(Opcjonalnie) Jeśli artykuł jest filtrowany poziomo, określ klauzulę filtra wierszowego dla tej FilterClause właściwości. Użyj tej właściwości, aby określić statyczny lub parametryzowany filtr wierszowy. Aby uzyskać więcej informacji, zobacz Sparametryzowane filtry wierszy.
Aby uzyskać więcej informacji, zobacz Definiowanie artykułu.
Wywołaj metodę Create .
Powtórz kroki 5 i 6 dla każdego artykułu tworzącego zapis logiczny.
Stwórz instancję klasy MergeJoinFilter , aby zdefiniować logiczne powiązania rekordów między artykułami. Następnie ustaw następujące właściwości:
Nazwa artykułu podrzędnego w logicznej relacji rekordów dla właściwości ArticleName.
Nazwa istniejącego rekordu nadrzędnego w logicznej relacji rekordów dla właściwości JoinArticleName.
Nazwa logicznej relacji rekordu dla właściwości FilterName.
Wyrażenie definiujące zależność dla właściwości JoinFilterClause.
Wartość LogicalRecordLink dla właściwości FilterTypes. Jeśli relacja rekordu logicznego jest również filtrem sprzężenia, określ dla tej właściwości wartość JoinFilterAndLogicalRecordLink. Aby uzyskać więcej informacji, zobacz Grupowanie zmian w powiązanych wierszach z rekordami logicznymi.
Wywołaj metodę AddMergeJoinFilter dla obiektu, który reprezentuje artykuł podrzędny w relacji. Przekaż MergeJoinFilter obiekt z kroku 8, aby zdefiniować relację.
Powtórz kroki 8 i 9 dla każdej z pozostałych relacji rekordów logicznych w publikacji.
Przykład (RMO)
Ten przykład tworzy logiczny rekord obejmujący dwa nowe rekordy dla tabel SalesOrderHeader i SalesOrderDetail.
// 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
Treści powiązane
- Definiowanie i modyfikowanie filtru sprzęgającego między artykułami scalania
- Definiowanie i modyfikowanie sparametryzowanego filtru wierszy dla artykułu scalania
- Definiowanie i modyfikowanie statycznego filtru wierszy
- Grupowanie zmian w powiązanych wierszach za pomocą rekordów logicznych
- Filtry parametryzowane — optymalizacja dla wstępnie obliczonych partycji