マージ テーブル アーティクル間に論理レコード リレーションシップを定義する方法 (レプリケーション Transact-SQL プログラミング)
更新 : 2005 年 12 月 5 日
マージ レプリケーションでは、さまざまなテーブルの関連する行の間にリレーションシップを定義できます。これにより、同期の際に行をトランザクション単位として処理できます。論理レコードは、2 つのアーティクルの間に定義できます。結合フィルタ リレーションシップの有無は関係ありません。詳細については、「論理レコードによる関連行への変更のグループ化」を参照してください。プログラムでレプリケーション ストアド プロシージャを使用して、アーティクル間に論理レコード リレーションシップを指定できます。
関連する結合フィルタを使用せずに論理レコード リレーションシップを定義するには
フィルタ選択されたアーティクルがパブリケーションに含まれている場合、sp_helpmergepublication を実行して、結果セットの use_partition_groups の値を確認します。
- 値が 1 の場合、事前計算済みパーティションが既に使用されています。
- 値が 0 の場合、パブリッシャ側のパブリケーション データベースに対して sp_changemergepublication を実行します。@property には use_partition_groups を指定し、@value には true を指定します。
メモ : パブリケーションで事前計算済みパーティションがサポートされない場合、論理レコードは使用できません。詳細については、「事前計算済みパーティションによるパラメータ化されたフィルタのパフォーマンス最適化」の「事前計算済みパーティションによるパラメータ化されたフィルタのパフォーマンス最適化」を参照してください。 - この値が NULL の場合、パブリケーションの初期スナップショットを生成するためにスナップショット エージェントを実行する必要があります。
論理レコードを構成するアーティクルが存在しない場合は、パブリッシャ側のパブリケーション データベースに対して sp_addmergearticle を実行します。論理レコードの競合の検出と解決に関するオプションを次の中から 1 つ指定します。
- 論理レコードの関連する行で発生する競合を検出し、解決するには、@logical_record_level_conflict_detection および @logical_record_level_conflict_resolution に true を指定します。
- 標準の行レベルまたは列レベルの競合の検出と解決を使用するには、@logical_record_level_conflict_detection および @logical_record_level_conflict_resolution に false を指定します。これは既定の設定です。
論理レコードを構成する各アーティクルに対して、手順 2. を実行します。論理レコード内の各アーティクルに使用する競合の検出および解決のオプションは、すべて同じである必要があります。詳細については、「論理レコードの競合の検出および解決」を参照してください。
パブリッシャ側のパブリケーション データベースに対して、sp_addmergefilter を実行します。@publication を指定します。リレーションシップの 1 つのアーティクルの名前を @article に、もう 1 つのアーティクルの名前を @join_articlename に指定します。リレーションシップの名前を @filtername に、2 つのアーティクル間のリレーションシップを定義する句を @join_filterclause に、結合の種類を @join_unique_key に指定します。次のいずれかの値を @filter_type に指定します。
- 2 - 論理リレーションシップを定義します。
- 3 - 結合フィルタを使用した論理リレーションシップを定義します。
メモ : 結合フィルタを使用しない場合、2 つのアーティクル間のリレーションシップの方向はあまり重要でなくなります。 パブリケーションの他の論理レコード リレーションシップについても、手順 2. をそれぞれ実行します。
論理レコードにおける競合の検出と解決の方法を変更するには
論理レコードの関連する行で発生する競合を検出し、解決するには、次の手順を実行します。
- パブリッシャ側のパブリケーション データベースに対して、sp_changemergearticle を実行します。@property に logical_record_level_conflict_detection を指定し、@value に true を指定します。@force_invalidate_snapshot および @force_reinit_subscription に 1 を指定します。
- パブリッシャ側のパブリケーション データベースに対して、sp_changemergearticle を実行します。@property に logical_record_level_conflict_resolution を指定し、@value に true を指定します。@force_invalidate_snapshot および @force_reinit_subscription に 1 を指定します。
標準の行レベルまたは列レベルの競合の検出と解決を使用するには、次の手順を実行します。
- パブリッシャ側のパブリケーション データベースに対して、sp_changemergearticle を実行します。@property に logical_record_level_conflict_detection を指定し、@value に false を指定します。@force_invalidate_snapshot および @force_reinit_subscription に 1 を指定します。
- パブリッシャ側のパブリケーション データベースに対して、sp_changemergearticle を実行します。@property に logical_record_level_conflict_resolution を指定し、@value に false を指定します。@force_invalidate_snapshot および @force_reinit_subscription に 1 を指定します。
論理レコード リレーションシップを削除するには
パブリッシャ側のパブリケーション データベースに対して次のクエリを実行し、指定されたパブリケーションに対して定義されているすべての論理レコード リレーションシップに関する情報を返します。
SELECT f.* FROM sysmergesubsetfilters AS f INNER JOIN sysmergepublications AS p ON f.pubid = p.pubid WHERE p.[name] = @publication;
結果セット内の filtername 列で削除されている論理レコード リレーションシップの名前を確認します。
メモ : このクエリは、sp_helpmergefilter と同じ情報を返します。ただし、このシステム ストアド プロシージャは、結合フィルタでもある論理レコード リレーションシップに関する情報のみ返します。 パブリッシャ側のパブリケーション データベースに対して、sp_dropmergefilter を実行します。@publication を指定し、リレーションシップ内の 1 つのアーティクルの名前を @article に、手順 1. のリレーションシップの名前を @filtername に指定します。
使用例
この例では、既存のパブリケーションで事前計算済みパーティションを有効にし、SalesOrderHeader と SalesOrderDetail テーブルの 2 つの新しいアーティクルを含む論理レコードを作成しています。
-- 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