Share via


Procedura: Definizione di una relazione tra record logici degli articoli di tabelle di merge (programmazione Transact-SQL della replica)

[!NOTA]

Questa caratteristica verrà rimossa a partire da una delle prossime versioni di Microsoft SQL Server. Evitare di utilizzare questa funzionalità in un nuovo progetto di sviluppo e prevedere interventi di modifica nelle applicazioni in cui è attualmente implementata.

La replica di tipo merge consente di definire una relazione tra righe correlate in tabelle diverse. In tal modo le righe possono essere elaborate come un'unità transazionale durante la sincronizzazione. È possibile definire un record logico tra due articoli indipendentemente dal fatto che per essi sia stata definita una relazione tra filtri join. Per ulteriori informazioni, vedere Raggruppamento di modifiche alla righe correlate con record logici. Per specificare a livello di programmazione relazioni tra record logici tra gli articoli, è possibile utilizzare stored procedure di replica.

Per definire una relazione tra record logici senza un filtro join associato

  1. Se la pubblicazione contiene eventuali articoli con filtro, eseguire sp_helpmergepublication e notare il valore di use_partition_groups nel set di risultati.

    • Se il valore è 1, le partizioni calcolate vengono già utilizzate.

    • Se il valore è 0, eseguire sp_changemergepublication nel database di pubblicazione del server di pubblicazione. Specificare il valore use_partition_groups per @property e il valore true per @value.

      [!NOTA]

      Se la pubblicazione non supporta le partizioni calcolate, non sarà possibile utilizzare i record logici. Per ulteriori informazioni, vedere i requisiti per l'utilizzo delle partizioni precalcolate nell'argomento Ottimizzazione delle prestazioni dei filtri con parametri con le partizioni pre-calcolate.

    • Se il valore è NULL, è necessario eseguire l'agente snapshot per generare lo snapshot iniziale per la pubblicazione.

  2. Se gli articoli che includeranno il record logico non esistono, eseguire sp_addmergearticle nel database di pubblicazione del server di pubblicazione. Specificare una delle opzioni di rilevamento e risoluzione dei conflitti seguenti per il record logico:

    • Per rilevare e risolvere conflitti che si verificano all'interno di righe correlate del record logico, specificare il valore true per @logical_record_level_conflict_detection e @logical_record_level_conflict_resolution.

    • Per utilizzare l'opzione riga di rilevamento e risoluzione dei conflitti a livello di riga o di colonna, specificare il valore false per @logical_record_level_conflict_detection e @logical_record_level_conflict_resolution, che corrisponde all'impostazione predefinita.

  3. Ripetere il passaggio 2 per ogni articolo che includerà il record logico. È necessario utilizzare la stessa opzione di rilevamento e risoluzione dei conflitti per ogni articolo del record logico. Per ulteriori informazioni, vedere Rilevamento e risoluzione dei conflitti nei record logici.

  4. Nel database di pubblicazione del server di pubblicazione eseguire sp_addmergefilter. Specificare @publication, il nome di un articolo della relazione per @article, il nome del secondo articolo per @join_articlename, un nome per la relazione per @filtername, una clausola che definisce la relazione tra i due articoli @join_filterclause, il tipo di join per @join_unique_key e uno dei valori seguenti per @filter_type:

    • 2: consente di definire una relazione logica.

    • 3: consente di definire una relazione logica con un filtro join.

    [!NOTA]

    Se il filtro join non viene utilizzato, la direzione della relazione tra i due articoli non ha rilevanza.

  5. Ripetere il passaggio 2 per tutte le altre relazioni tra record logici incluse nella pubblicazione.

Per modificare l'opzione di rilevamento e risoluzione dei conflitti per i record logici

  1. Per rilevare e risolvere conflitti che si verificano all'interno di righe correlate nel record logico:

    • Nel database di pubblicazione del server di pubblicazione eseguire sp_changemergearticle. Specificare il valore logical_record_level_conflict_detection per @property e il valore true per @value. Specificare il valore 1 per @force_invalidate_snapshot e @force_reinit_subscription.

    • Nel database di pubblicazione del server di pubblicazione eseguire sp_changemergearticle. Specificare il valore logical_record_level_conflict_resolution per @property e il valore true per @value. Specificare il valore 1 per @force_invalidate_snapshot e @force_reinit_subscription.

  2. Per utilizzare l'opzione standard di rilevamento e risoluzione dei conflitti a livello di riga o di colonna:

    • Nel database di pubblicazione del server di pubblicazione eseguire sp_changemergearticle. Specificare il valore logical_record_level_conflict_detection per @property e il valore false per @value. Specificare il valore 1 per @force_invalidate_snapshot e @force_reinit_subscription.

    • Nel database di pubblicazione del server di pubblicazione eseguire sp_changemergearticle. Specificare il valore logical_record_level_conflict_resolution per @property e il valore false per @value. Specificare il valore 1 per @force_invalidate_snapshot e @force_reinit_subscription.

Per rimuovere una relazione tra record logici

  1. Nel database di pubblicazione del server di pubblicazione eseguire la query seguente per restituire informazioni su tutte le relazioni tra record logici definite per la pubblicazione specificata:

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

    Si noti il nome della relazione tra record logici da rimuovere nella colonna filtername del set di risultati.

    [!NOTA]

    Questa query restituisce le stesse informazioni di sp_helpmergefilter. La stored procedure di sistema restituisce tuttavia solo le informazioni sulle relazioni tra record logici che corrispondono anche a filtri join.

  2. Nel database di pubblicazione del server di pubblicazione eseguire sp_dropmergefilter. Specificare @publication, il nome di uno degli articoli della relazione per @article e il nome della relazione ottenuto al passaggio 1 per @filtername.

Esempio

In questo esempio le partizioni calcolate vengono attivate in una pubblicazione esistente e viene creato un record logico che comprende i due nuovi articoli per le tabelle 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