定義和修改合併發行項之間的聯結篩選

適用於:SQL Server

本主題說明如何使用 SQL Server Management Studio 或 Transact-SQL,在 SQL Server 中定義和修改合併發行項之間的聯結篩選。 合併式複寫支援聯結篩選,聯結篩選通常會配合參數化篩選一起使用,以將資料表資料分割擴充到其他相關的資料表發行項。

本主題內容

開始之前

限制事項

  • 若要建立聯結篩選,發行集至少必須包含兩個相關的資料表。 聯結篩選會擴充資料列篩選;因此您必須先定義一個資料表上的資料列篩選,然後才可利用聯結在另一個資料表上擴充篩選。 定義好一個聯結篩選後,如果發行集包含其他相關資料表,您可以用另一個聯結篩選擴充這個聯結篩選。

  • 如果您在初始化發行集的訂閱後,新增、修改或刪除聯結篩選,則必須在進行變更後產生新的快照集並重新初始化所有訂閱。 如需屬性變更需求的詳細資訊,請參閱變更發行集與發行項屬性

建議

使用 SQL Server Management Studio

您可以在 [新增發行集精靈] 的 [篩選資料表的資料列] 頁面上,或是在 [發行集屬性 - <發行集>] 對話方塊的 [篩選資料列] 頁面上,定義、修改及刪除聯結篩選。 如需使用精靈及存取對話方塊的詳細資訊,請參閱建立發行集檢視及修改發行集屬性

若要定義聯結篩選

  1. 在 [新增發行集精靈] 的 [篩選資料表的資料列] 頁面上,或是在 [發行集屬性 - <發行集>] 對話方塊的 [篩選資料列] 頁面上,從 [已篩選的資料表] 窗格中選取一個現有的資料列篩選或聯結篩選。

  2. 按一下 [加入] ,然後按一下 [加入聯結以擴充選取的篩選]

  3. 建立聯結陳述式:選取 [使用產生器建立陳述式] 或 [手動寫入 join 陳述式] 。

    • 如果選取使用產生器,請使用方格中的資料行 ([結合]、[已篩選的資料表資料行] 、[運算子] 和 [聯結的資料表資料行] ) 來建立聯結陳述式。

      方格中的每個資料行都包含下拉式方塊,可讓您選取兩個資料行和一個運算子 (=<><=<>=> 以及 like)。 結果會在 [預覽] 文字區域中顯示。 如果聯結涉及多對資料行,請從 [結合] 資料行中選取一個結合 (AND 或 OR),然後輸入兩個或更多的資料行及一個運算子。

    • 如果選取手動寫入陳述式,請在 [聯結陳述式] 文字區域寫入聯結陳述式。 使用 [已篩選的資料表資料行] 清單方塊與 [聯結的資料表資料行] 清單方塊將資料行拖放到 [Join 陳述式] 文字區域。

    • 完整的聯結陳述式應類似於:

      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

另請參閱

Join Filters
參數化資料列篩選器
變更發行集與發行項屬性
合併式複寫之篩選發行資料
操作說明:定義和修改合併發行項之間的聯結篩選 (SQL Server Management Studio)
Replication System Stored Procedures Concepts
定義合併資料表發行項之間的邏輯記錄關聯性
針對合併發行項定義及修改參數化資料列篩選