定义和修改合并项目间的联接筛选器

适用于:SQL Server

本主题介绍如何使用 SQL Server Management Studio 或 Transact-SQL 在 SQL Server 中定义和修改合并项目之间的联接筛选器。 合并复制支持联接筛选器,这类筛选器通常与参数化筛选器配合使用,以将表分区扩展到其他相关的表项目。

本主题内容

开始之前

限制和局限

  • 若要创建联接筛选器,发布必须至少包含两个相关表。 联接筛选器可扩展行筛选器;因此必须先对一个表定义行筛选器,才能使用联接将该筛选器扩展到另一个表。 定义一个联接筛选器后,如果发布包含更多相关表,则可使用其他联接筛选器来扩展此联接筛选器。

  • 如果在初始化对发布的订阅后添加、修改或删除联接筛选器,必须在更改后生成新的快照并重新初始化所有订阅。 有关属性更改要求的详细信息,请参阅更改发布和项目属性

建议

使用 SQL Server Management Studio

在新建发布向导的“筛选表行”页或“发布属性 - <发布>”对话框的“筛选行”页上定义、修改和删除联接筛选器。 有关如何使用该向导和如何访问该对话框的详细信息,请参阅创建发布查看和修改发布属性

定义联接筛选器

  1. 在新建发布向导的“筛选表行”页或“发布属性 - <发布>”的“筛选行”页上,在“筛选的表”窗格中选择现有行筛选器或联接筛选器。

  2. 单击 “添加”,再单击 “添加联接以扩展所选筛选器”

  3. 创建联接语句:选择 “使用生成器创建语句”“手动编写联接语句”

    • 如果选择使用生成器,请使用网格中的列(“连接”“筛选的表列”“运算符”、和 “联接的表列”)生成联接语句。

      网格中的每列都包含一个下拉组合框,允许选择两列和一个运算符(=<>、<=<、>=> 和 like)。 结果显示在 “预览” 文本区域中。 如果联接中涉及多个列对,则从 “连接词” 列中选择一个连接词(AND 或 OR),然后再输入两列和一个运算符。

    • 如果选择手动编写语句,那么请在 “联接语句” 文本区域编写联接语句。 使用 “筛选的表列” 列表框和 “联接的表列” 列表框将列拖放到 “联接语句” 文本区域。

    • 完整的联接语句如下所示:

      SELECT <published_columns> FROM [Sales].[SalesOrderHeader] INNER JOIN [Sales].[SalesOrderDetail] ON [SalesOrderHeader].[SalesOrderID] = [SalesOrderDetail].[SalesOrderID]  
      

      JOIN 子句应使用由两个部分组成的名称来命名;它不支持由三个部分和四个部分组成的名称命名。

  4. 指定联接选项:

    • 如果在筛选的表(父表)中联接的列是唯一的,则选择 “唯一键”

      注意

      选择此选项表示联接筛选器中子表和父表是一对一还是一对多的关系。 仅当子表的联接列上具有保证唯一性的约束时才选择此选项。 如果未能正确设置此选项,可能无法收敛数据。

    • 默认情况下,合并复制在同步过程中会逐行处理更改。 要将筛选的表行和联接的表行中的相关更改作为一个单元进行处理,请选择“逻辑记录”(仅适用于 Microsoft SQL Server 2005 (9.x) 及更高版本)。 只有满足使用逻辑记录的项目和发布要求,此选项才可用。 有关详细信息,请参阅通过逻辑记录对相关行的更改进行分组中的“使用逻辑记录的注意事项”部分。

  5. 选择“确定”

  6. 如果处于“发布属性 - <发布>”对话框中,请单击“确定”以保存并关闭该对话框。

修改联接筛选器

  1. 在新建发布向导的“筛选表行”页或“发布属性 - <发布>”的“筛选行”页上,在“筛选的表”窗格中选择筛选器,然后单击“编辑”

  2. “编辑联接” 对话框中,修改筛选器。

  3. 选择“确定”

删除联接筛选器

  1. 在新建发布向导的“筛选表行”页或“发布属性 - <发布>”的“筛选行”页上,在“筛选的表”窗格中选择筛选器,然后单击“删除”。 如果删除的联接筛选器自身是由其他联接扩展而成的,则也将删除那些联接。

“使用 Transact-SQL”

这些过程显示了父项目上的参数化筛选器以及该项目和相关子项目间的联接筛选器。 可以使用复制存储过程,以编程方式定义和修改联接筛选器。

定义联接筛选器以将项目筛选器扩展到合并发布中的相关项目

  1. 为要联接到的项目(又称为父项目)定义筛选。

  2. 在发布数据库中的发布服务器上,执行 sp_addmergearticle (Transact-SQL),为发布定义一个或多个相关项目(又称为子项目)。 有关详细信息,请参阅 定义项目

  3. 在发布数据库中的发布服务器上,执行 sp_addmergefilter (Transact-SQL)。 指定 @publication,为 @filtername 指定此筛选器的唯一名称,为 @article 指定在步骤 2 中创建的子项目的名称,为 @join_articlename 指定要联接到的父项目的名称,并为 @join_unique_key 指定以下值之一:

    • 0 - 表示父项目与子项目间的多对一或多对多联接。

    • 1 - 表示父项目与子项目间的一对一或一对多联接。

    此步骤定义了两个项目间的联接筛选器。

    注意

    仅当对父项目的基础表中的联接列具有可保证唯一性的约束时,才将 @join_unique_key 设置为 1。 如果错误地将 @join_unique_key 设置为 1,则可能无法收敛数据

示例 (Transact-SQL)

此示例定义了合并发布的项目,并针对 SalesOrderDetail 表来筛选 SalesOrderHeader 表项目,而该表本身使用静态行筛选器进行筛选。 有关详细信息,请参阅 Define and Modify a Static Row Filter

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);
SET @publication = N'AdvWorksSalesOrdersMerge'; 
SET @table1 = N'Employee'; 
SET @table2 = N'SalesOrderHeader'; 
SET @table3 = N'SalesOrderDetail'; 
SET @salesschema = N'Sales';
SET @hrschema = N'HumanResources';
SET @filterclause = N'Employee.LoginID = HOST_NAME()';

-- 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 that is filtered
-- based on Employee and horizontally filtered.
EXEC sp_addmergearticle 
  @publication = @publication, 
  @article = @table2, 
  @source_object = @table2, 
  @type = N'table', 
  @source_owner = @salesschema, 
  @vertical_partition = N'true',
  @schema_option = 0x0034EF1,
  @description = N'article for the SalesOrderDetail table';

-- Add an article for the SalesOrderDetail table that is filtered
-- based on SaledOrderHeader.
EXEC sp_addmergearticle 
  @publication = @publication, 
  @article = @table3, 
  @source_object = @table3, 
  @source_owner = @salesschema,
  @description = 'article for the SalesOrderHeader table', 
  @identityrangemanagementoption = N'auto', 
  @pub_identity_range = 100000, 
  @identity_range = 100, 
  @threshold = 80,
  @schema_option = 0x0004EF1;

-- Add all columns to the SalesOrderHeader article.
EXEC sp_mergearticlecolumn 
  @publication = @publication, 
  @article = @table2, 
  @force_invalidate_snapshot = 1, 
  @force_reinit_subscription = 1;

-- Remove the credit card Approval Code column.
EXEC sp_mergearticlecolumn 
  @publication = @publication, 
  @article = @table2, 
  @column = N'CreditCardApprovalCode', 
  @operation = N'drop', 
  @force_invalidate_snapshot = 1, 
  @force_reinit_subscription = 1;

-- 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.BusinessEntityID = SalesOrderHeader.SalesPersonID', 
  @join_unique_key = 1, 
  @filter_type = 1, 
  @force_invalidate_snapshot = 1, 
  @force_reinit_subscription = 1;

-- Add a merge join filter between SalesOrderHeader and SalesOrderDetail.
EXEC sp_addmergefilter 
  @publication = @publication, 
  @article = @table3, 
  @filtername = N'SalesOrderDetail_SalesOrderHeader', 
  @join_articlename = @table2, 
  @join_filterclause = N'SalesOrderHeader.SalesOrderID = SalesOrderDetail.SalesOrderID', 
  @join_unique_key = 1, 
  @filter_type = 1, 
  @force_invalidate_snapshot = 1, 
  @force_reinit_subscription = 1;
GO

此示例定义了合并发布中的一组项目,并针对 Employee 表使用一系列联接筛选器来筛选这些项目,而该表本身则使用参数化行筛选器按 LoginID 列中的 HOST_NAME 值进行筛选。 有关详细信息,请参阅 定义和修改合并项目的参数化行筛选器

-- To avoid storing the login and password in the script file, the value 
-- is passed into SQLCMD as a scripting variable. For information about 
-- how to use scripting variables on the command line and in SQL Server
-- Management Studio, see the "Executing Replication Scripts" section in
-- the topic "Programming Replication Using System Stored Procedures".

--Add a new merge publication.
DECLARE @publicationdb AS sysname;
DECLARE @publication AS sysname;
DECLARE @table1 AS sysname;
DECLARE @table2 AS sysname;
DECLARE @filter AS sysname;
DECLARE @schema_hr AS sysname;
DECLARE @schema_sales AS sysname;

SET @publicationdb = N'AdventureWorks2022';
SET @publication = N'AdvWorksSalesPersonMerge';
SET @table1 = N'Employee';
SET @table2 = N'SalesPerson';
SET @filter = N'SalesPerson_Employee';
SET @schema_hr = N'HumanResources';
SET @schema_sales = N'Sales';

USE [AdventureWorks2022];

-- Enable AdventureWorks2022 for merge replication.
EXEC sp_replicationdboption
  @dbname = @publicationdb,
  @optname = N'merge publish',
  @value = N'true';  

-- Create new merge publication with Subscriber requested snapshot
-- and using the default agent schedule. 
EXEC sp_addmergepublication 
  @publication = @publication, 
  @description = N'Merge publication of AdventureWorks2022.', 
  @allow_subscriber_initiated_snapshot = N'true',
  @publication_compatibility_level = N'90RTM';

-- Create a new snapshot job for the publication, using the default schedule.
-- Pass credentials at runtime using sqlcmd scripting variables.
EXEC sp_addpublication_snapshot 
  @publication = @publication, 
  @job_login = $(login), 
  @job_password = $(password);

-- Add an article for the Employee table, 
-- which is horizontally partitioned using 
-- a parameterized row filter.
EXEC sp_addmergearticle 
  @publication = @publication, 
  @article = @table1, 
  @source_owner = @schema_hr, 
  @source_object = @table1, 
  @type = N'table', 
  @description = 'contains employee information', 
  @subset_filterclause = N'[LoginID] = HOST_NAME()';

-- Add an article for the SalesPerson table, 
-- which is partitioned based on a join filter.
EXEC sp_addmergearticle 
  @publication = @publication, 
  @article = @table2, 
  @source_owner = @schema_sales, 
  @source_object = @table2, 
  @type = N'table', 
  @description = 'contains salesperson information';

-- Add a join filter between the two articles.
EXEC sp_addmergefilter 
  @publication = @publication, 
  @article = @table1, 
  @filtername = @filter, 
  @join_articlename = @table2, 
  @join_filterclause = N'[Employee].[BusinessEntityID] = [SalesPerson].[SalesPersonID]', 
  @join_unique_key = 1, 
  @filter_type = 1;
GO

-- Start the agent job to generate the full snapshot for the publication.
-- The filtered data snapshot is generated automatically the first time 
-- the subscription is synchronized. 
DECLARE @publication AS sysname;
SET @publication = N'AdvWorksSalesPersonMerge';

EXEC sp_startpublication_snapshot 
  @publication = @publication;
GO

另请参阅

联接筛选器
参数化行筛选器
更改发布和项目属性
为合并复制筛选已发布数据
如何定义和修改合并项目间的联接筛选器 (SQL Server Management Studio)
Replication System Stored Procedures Concepts
定义合并表项目间的逻辑记录关系
定义和修改合并项目的参数化行筛选器