방법: 병합 테이블 아티클 간의 논리적 레코드 관계 정의(복제 Transact-SQL 프로그래밍)

[!참고]

Microsoft SQL Server의 이후 버전에서는 이 기능이 제거됩니다. 새 개발 작업에서는 이 기능을 사용하지 않도록 하고, 현재 이 기능을 사용하는 응용 프로그램은 수정하십시오.

병합 복제를 사용하면 서로 다른 테이블에 있는 관련 행 간의 관계를 정의할 수 있습니다. 즉, 동기화 중에 이러한 행들을 하나의 트랜잭션으로 처리할 수 있습니다. 논리적 레코드는 조인 필터 관계가 있는지 여부와 관계없이 두 아티클 간에 정의할 수 있습니다. 자세한 내용은 논리적 레코드를 사용하여 관련된 행의 변경 내용을 그룹화를 참조하십시오. 복제 저장 프로시저를 사용하여 아티클 간 논리적 레코드 관계를 프로그래밍 방식으로 지정할 수 있습니다.

관련된 조인 필터 없이 논리적 레코드 관계를 정의하려면

  1. 게시에 필터링된 아티클이 포함되어 있으면 sp_helpmergepublication을 실행하고 결과 집합에서 use_partition_groups의 값을 확인합니다.

    • 이 값이 1이면 사전 계산 파티션이 이미 사용되고 있는 것입니다.

    • 이 값이 0이면 게시 데이터베이스의 게시자에서 sp_changemergepublication을 실행합니다. @propertyuse_partition_groups 값을 지정하고 @valuetrue 값을 지정합니다.

      [!참고]

      게시에서 사전 계산 파티션을 지원하지 않으면 논리적 레코드를 사용할 수 없습니다. 자세한 내용은 사전 계산 파티션으로 매개 변수가 있는 필터 성능 최적화 항목의 사전 계산 파티션을 사용하기 위한 요구 사항을 참조하십시오.

    • 이 값이 NULL이면 스냅숏 에이전트를 실행하여 게시에 대한 초기 스냅숏을 생성해야 합니다.

  2. 논리적 레코드를 구성하는 아티클이 없으면 게시 데이터베이스의 게시자에서 sp_addmergearticle을 실행합니다. 논리적 레코드에 대해 다음 충돌 감지 및 해결 옵션 중 하나를 지정합니다.

    • 논리적 레코드의 관련 행 내에서 발생하는 충돌을 감지하여 해결하려면 @logical_record_level_conflict_detection@logical_record_level_conflict_resolution 값을 true로 지정합니다.

    • 표준 행 수준 또는 열 수준의 충돌 감지 및 해결을 사용하려면 @logical_record_level_conflict_detection@logical_record_level_conflict_resolutionfalse 값(기본값)을 지정합니다.

  3. 논리적 레코드를 구성하는 각 아티클에 대해 2단계를 반복합니다. 논리적 레코드의 각 아티클에 대해 동일한 충돌 감지 및 해결 옵션을 사용해야 합니다. 자세한 내용은 논리적 레코드에서 충돌 감지 및 해결을 참조하십시오.

  4. 게시 데이터베이스의 게시자에서 sp_addmergefilter를 실행합니다. @publication을 지정하고 @article에 관계 구성 아티클 중 하나의 이름을, @join_articlename에 두 번째 아티클의 이름을, @filtername에 관계의 이름을, @join_filterclause에 두 아티클 간 관계를 정의하는 절을, @join_unique_key에 조인 형식을 지정하고 @filter_type에 다음 값 중 하나를 지정합니다.

    • 2 - 논리적 관계를 정의합니다.

    • 3 - 조인 필터를 포함하는 논리적 관계를 정의합니다.

    [!참고]

    조인 필터를 사용하지 않는 경우 두 아티클 간의 관계 방향은 중요하지 않습니다.

  5. 게시에서 남은 각각의 논리적 레코드 관계에 대해 2단계를 반복합니다.

논리적 레코드에 대한 충돌 감지 및 해결을 변경하려면

  1. 논리적 레코드의 관련 행 내에서 발생하는 충돌을 감지하고 해결하려면 다음을 수행합니다.

    • 게시 데이터베이스의 게시자에서 sp_changemergearticle을 실행합니다. @propertylogical_record_level_conflict_detection 값을 지정하고 @valuetrue 값을 지정합니다. @force_invalidate_snapshot@force_reinit_subscription에 값 1을 지정합니다.

    • 게시 데이터베이스의 게시자에서 sp_changemergearticle을 실행합니다. @propertylogical_record_level_conflict_resolution 값을 지정하고 @valuetrue 값을 지정합니다. @force_invalidate_snapshot@force_reinit_subscription에 값 1을 지정합니다.

  2. 표준 행 수준 또는 열 수준의 충돌 감지 및 해결을 사용하려면 다음을 수행합니다.

    • 게시 데이터베이스의 게시자에서 sp_changemergearticle을 실행합니다. @propertylogical_record_level_conflict_detection 값을 지정하고 @valuefalse 값을 지정합니다. @force_invalidate_snapshot@force_reinit_subscription에 값 1을 지정합니다.

    • 게시 데이터베이스의 게시자에서 sp_changemergearticle을 실행합니다. @propertylogical_record_level_conflict_resolution 값을 지정하고 @valuefalse 값을 지정합니다. @force_invalidate_snapshot@force_reinit_subscription에 값 1을 지정합니다.

논리적 레코드 관계를 제거하려면

  1. 게시 데이터베이스의 게시자에서 다음 쿼리를 실행하여 지정된 게시에 대해 정의된 모든 논리적 레코드 관계 정보를 반환합니다.

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

    결과 집합의 filtername 열에서 제거되고 있는 논리적 레코드 관계의 이름을 확인합니다.

    [!참고]

    이 쿼리는 sp_helpmergefilter와 동일한 정보를 반환하지만, 이 시스템 저장 프로시저는 조인 필터이기도 한 논리적 레코드 관계에 대한 정보만 반환합니다.

  2. 게시 데이터베이스의 게시자에서 sp_dropmergefilter를 실행합니다. @publication을 지정하고 @article에 대해 관계 구성 아티클 중 하나의 이름을, @filtername에 대해 1단계에서 사용된 관계의 이름을 지정합니다.

이 예에서는 기존 게시에 사전 계산 파티션을 사용하고 SalesOrderHeader 및 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