如何定义合并表项目之间的逻辑记录关系(复制 Transact-SQL 编程)
注意 |
---|
后续版本的 Microsoft SQL Server 将删除该功能。 请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。 |
您可以使用合并复制来定义不同表中相关行之间的关系。也就是说,在同步期间可将行作为事务单元进行处理。无论两个项目之间是否存在联接筛选器关系,都可以在这两个项目之间定义逻辑记录。有关详细信息,请参阅通过逻辑记录对相关行的更改进行分组。您可以使用复制存储过程以编程方式指定项目之间的逻辑记录关系。
在没有关联的联接筛选器的情况下定义逻辑记录关系
如果发布包含已筛选的任何项目,则执行 sp_helpmergepublication,并注意结果集中的 use_partition_groups 值。
如果值为 1,则已使用预计算分区。
如果值为 0,请在发布服务器上对发布数据库执行 sp_changemergepublication。将 @property 的值指定为 use_partition_groups 并将 @value 的值指定为 true。
注意 如果发布不支持预计算分区,则无法使用逻辑记录。有关详细信息,请参阅主题使用预计算分区优化参数化筛选器的性能中的“使用预计算分区的要求”。
如果值为 NULL,则需要运行快照代理以生成发布的初始快照。
如果将包含逻辑记录的项目不存在,请在发布服务器上对发布数据库执行 sp_addmergearticle。为逻辑记录指定以下冲突检测和解决选项中的一项:
若要检测并解决发生在逻辑记录的相关行之间的冲突,请将 @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,将 @article 指定为该关系中一个项目的名称,将 @join_articlename 指定为第二个项目的名称,将 @filtername 指定为该关系的名称,将 @join_filterclause 指定为定义两个项目之间关系的子句,将**@join_unique_key** 指定为联接的类型,并将 @filter_type 指定为以下值之一:
2 - 定义逻辑关系。
3 - 定义与联接筛选器的逻辑关系。
注意 如果未使用联接筛选器,则两个项目之间的关系方向并不重要。
为发布中剩余的每个逻辑记录关系重复步骤 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,为 @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