使用參數化篩選建立合併式發行集的快照集

適用於:SQL Server

本主題說明如何使用 SQL Server Management Studio、Transact-SQL 或 Replication Management Objects (RMO),在 SQL Server 中使用參數化篩選來建立合併式發行集的快照。

在合併發行集內使用參數化資料列篩選器時,覆寫會以兩段式的快照集來初始化每一個訂閱。 首先建立包含複寫所需之所有物件以及已發行物件之結構描述的結構描述快照集,但不含資料。 然後使用包含結構描述快照集中物件與結構描述以及訂閱之資料分割所屬資料的快照集,來初始化每個訂閱。 如果有多個訂閱收到給定的資料分割 (即收到相同的結構描述和資料),該資料分割的快照集只會建立一次,多個訂閱均從同一快照集初始化。 如需參數化資料列篩選器的詳細資訊,請參閱< 參數化資料列篩選器>。

您可以使用下列三種方法之一為含參數化篩選的發行集建立快照集:

  • 為每個資料分割預先產生快照集。 您可以使用此選項控制快照集的產生時間。
    您也可以選擇在排程時間重新整理快照集。 訂閱至已建立快照集之資料分割的新「訂閱者」,將收到最新的快照集。

  • 允許訂閱者在首次執行同步處理時,要求產生快照集及要求應用程式。 使用此選項可讓新「訂閱者」執行同步處理,而無需管理員介入 (必須在「發行者」端執行 SQL Server Agent,才允許產生快照集)。

    注意

    如果發行集內的一或多個發行項的篩選產生對每個訂閱而言是唯一的非重疊資料分割,則只要合併代理程式一執行,就會清除中繼資料。 這表示分割快照集會更快過期。 使用這個選項時,您應該考慮允許訂閱者初始化快照集的產生與傳遞。 如需有關篩選選項的詳細資訊,請參閱< 參數化資料列篩選器>。

  • 使用「快照集代理程式」為每個「訂閱者」手動產生快照集。 然後,「訂閱者」必須為「合併代理程式」提供快照集位置,才能擷取和套用正確的快照集。

    注意

    此選項支援回溯相容性,不允許 FTP 快照集共用。

最靈活的方法是將預先產生的快照集選項和「訂閱者」要求的快照集選項組合使用:快照集會預先產生,並在排程時間重新整理 (通常在離峰時段),但如果建立了需要新資料分割的訂閱,則「訂閱者」可以產生自己的快照集。

請考慮使用 Adventure Works,此產品具有行動工作能力,可將庫存傳遞至個別商店。 每個業務員都會收到其登入帳戶的訂閱 (擷取業務員服務之商店的資料)。 管理員選擇預先產生快照集,並在每個週日重新整理這些快照集。 偶而,會有新使用者新增到系統中,並且需要無可用快照集之資料分割中的資料。 管理員也可以選擇允許「訂閱者」初始化的快照集,以避免由於快照集不可用而造成「訂閱者」無法訂閱發行集的情況。 當新的「訂閱者」首次進行連接時,會為指定的資料分割建立快照集,並套用到「訂閱者」(必須在「發行者」端執行 SQL Server Agent,才允許產生快照集)。

若要為含參數化篩選的發行集建立快照集,請參閱< 使用參數化篩選建立合併式發行集的快照集>。

快照集代理程式的安全性設定

「快照集代理程式」會為每個資料分割建立快照集。 對於預先產生的快照集和「訂閱者」所需的快照集,代理程式會在建立發行集的快照集代理程式作業 (此作業由「新增發行集精靈」或 sp_addpublication_snapshot建立) 時指定的認證下執行並進行連接。 若要變更認證,請使用 sp_changedynamicsnapshot_job。 如需詳細資訊,請參閱 sp_changedynamicsnapshot_job (Transact-SQL)

建議

  • 在使用參數化篩選產生合併式發行集的快照集時,您必須先產生一個標準 (結構描述) 快照集,其中包含所有發行的資料以及訂閱的訂閱者中繼資料。 如需詳細資訊,請參閱 建立和套用初始快照集。 在您建立結構描述快照集之後,您可以產生包含發行資料之訂閱者特有資料分割的快照集。

  • 如果發行集內的一或多個發行項的篩選產生對每個訂閱而言是唯一的非重疊資料分割,則只要合併代理程式一執行,就會清除中繼資料。 這表示分割快照集會更快過期。 使用這個選項時,您應該考慮允許訂閱者初始化快照集的產生與傳遞。

使用 SQL Server Management Studio

您可以在 [發行集屬性 - <發行集>] 對話方塊的 [資料分割] 頁面上,產生資料分割的快照集。 如需有關存取這個對話方塊的詳細資訊,請參閱< View and Modify Publication Properties>。 您可以讓訂閱者初始化快照集產生和傳遞,並且/或者產生快照集。

產生一個或多個資料分割的快照集之前,必須:

  1. 使用「新增發行集精靈」建立合併發行集,並在精靈的 [加入篩選] 頁面上,指定一個或多個參數化資料列篩選器。 如需詳細資訊,請參閱 針對合併發行項定義及修改參數化資料列篩選

  2. 產生發行集的結構描述快照集。 依預設,當您完成「新增發行集精靈」時,便會產生結構描述快照集;您也可以從 SQL Server Management Studio 產生結構描述快照集。

若要產生結構描述快照集

  1. 連線到 Management Studio 中的發行者,然後展開伺服器節點。

  2. 展開 [複寫] 資料夾,然後展開 [發行集] 資料夾。

  3. 以滑鼠右鍵按一下您要為其建立快照集的發行集,然後按一下 [檢視快照集代理程式的狀態]

  4. 在 [檢視快照集代理程式的狀態 - <發行集>] 對話方塊中,按一下 [啟動]。

    快照集代理程式產生完快照集後,就會顯示一個訊息,例如「[100%] 已產生 17 個發行項的快照集」。

若要允許訂閱者初始化快照集的產生與傳遞

  1. 在 [發行集屬性 - <發行集>] 對話方塊的 [資料分割] 頁面上,選取 [新的訂閱者嘗試進行同步處理時,自動定義資料分割並依需要產生快照]。

  2. 選取 [確定]。

若要產生和重新整理快照集

  1. 在 [發行集屬性 - <發行集>] 對話方塊的 [資料分割] 頁面上,按一下 [新增]。

  2. 輸入與您要建立快照集的資料分割關聯之 HOST_NAME() 和 (或) SUSER_SNAME() 的值。

  3. 選擇性地指定重新整理快照集的排程:

    1. 選取 [排程這個資料分割的快照集代理程式在下列時間執行]

    2. 接受重新重理快照集的預設排程,或按一下 [變更] 以指定其他排程。

  4. 按一下 [確定] 回到 [發行集屬性 - <發行集>] 對話方塊。

  5. 在屬性方格中選取資料分割,然後按一下 [立即產生選取的快照集]

  6. 選取 [確定]。

使用 TRANSACT-SQL

您可以使用預存程序和快照集代理程式進行以下作業:

  • 允許訂閱者在首次執行同步處理時,要求快照集產生和應用程式。

  • 為每個資料分割預先產生快照集。

  • 以手動方式為每一個訂閱者產生快照集。

    重要

    可能的話,會在執行階段提示使用者輸入安全性認證。 如果您必須將認證儲存在指令碼檔案中,則必須維護這個檔案的安全性,使他人無法在未獲授權的情況下擅自存取。

建立可讓訂閱者初始化快照集產生和傳遞的發行集

  1. 在發行集資料庫的發行者端,執行 sp_addmergepublication (Transact-SQL)。 指定下列參數:

    • @publication設定為發行集的名稱。

    • @allow_subscriber_initiated_snapshot 設定為 true的值,這樣可讓訂閱者起始快照集處理。

    • (選擇性) 將 @max_concurrent_dynamic_snapshots設定為可以並行執行的動態快照集處理序數目。 如果正在執行最大的處理序數目,而且訂閱者嘗試產生快照集,則會將此處理序置於佇列中。 根據預設,並行處理序的數目沒有任何限制。

  2. 在發行者端,執行 sp_addpublication_snapshot (Transact-SQL)。 為 @publication 指定步驟 1 中所使用的發行集名稱,並為 @job_login@password 指定複寫快照集代理程式執行時所使用的 Microsoft Windows 認證。 如果代理程式會在連接到發行者時使用 SQL Server 驗證,您也必須為 @publisher_security_mode 指定 0 值,並為 @publisher_login@publisher_password 指定 Microsoft SQL Server 的登入資訊。 這麼做會為發行集建立快照集代理程式作業。 如需有關產生初始快照集以及為快照集代理程式定義自訂排程的詳細資訊,請參閱< Create and Apply the Initial Snapshot>。

    重要

    當利用遠端散發者來設定發行者時,提供給所有參數的值 (包括 job_loginjob_password) 都會以純文字的方式傳給散發者。 您應該先加密「發行者」及其遠端「散發者」之間的連接,再執行這個預存程序。 如需詳細資訊,請參閱啟用資料庫引擎的加密連線 (SQL Server 組態管理員)

  3. 若要將發行項新增至發行集中,請執行 sp_addmergearticle (Transact-SQL)。 必須針對發行集中的每一個發行項執行一次此預存程序。 在使用參數化篩選時,您必須使用 @subset_filterclause 參數來指定一個或多個發行項的參數化資料列篩選器。 如需詳細資訊,請參閱 針對合併發行項定義及修改參數化資料列篩選

  4. 如果將根據參數化資料列篩選器來篩選其他發行項,請執行 sp_addmergefilter (Transact-SQL) 來定義兩個發行項之間的聯結或邏輯記錄關聯性。 必須針對每一個定義的關聯性執行一次此預存程序。 如需詳細資訊,請參閱 定義和修改合併發行項之間的聯結篩選

  5. 當合併代理程式要求此快照集初始化訂閱者時,會自動產生要求之訂閱資料分割的快照集。

建立發行集及預先產生或自動重新整理快照集

  1. 若要建立發行集,請執行 sp_addmergepublication (Transact-SQL)。 如需詳細資訊,請參閱建立發行集

  2. 在發行者端,執行 sp_addpublication_snapshot (Transact-SQL)。 針對 @publication 指定步驟 1 中所使用的發行集名稱,以及針對 @job_login@password指定快照集代理程式執行時所使用的 Windows 認證。 如果代理程式會在連接到發行者時使用 SQL Server 驗證,您也必須為 @publisher_security_mode 指定 0 值,並為 @publisher_login@publisher_password 指定 SQL Server 的登入資訊。 這麼做會為發行集建立快照集代理程式作業。 如需有關產生初始快照集以及為快照集代理程式定義自訂排程的詳細資訊,請參閱< Create and Apply the Initial Snapshot>。

    重要

    當利用遠端散發者來設定發行者時,提供給所有參數的值 (包括 job_loginjob_password) 都會以純文字的方式傳給散發者。 您應該先加密「發行者」及其遠端「散發者」之間的連接,再執行這個預存程序。 如需詳細資訊,請參閱啟用資料庫引擎的加密連線 (SQL Server 組態管理員)

  3. 若要將發行項新增至發行集中,請執行 sp_addmergearticle (Transact-SQL)。 必須針對發行集中的每一個發行項執行一次此預存程序。 在使用參數化篩選時,您必須使用 @subset_filterclause 參數來指定一個發行項的參數化資料列篩選器。 如需詳細資訊,請參閱 針對合併發行項定義及修改參數化資料列篩選

  4. 如果將根據參數化資料列篩選器來篩選其他發行項,請執行 sp_addmergefilter (Transact-SQL) 來定義兩個發行項之間的聯結或邏輯記錄關聯性。 必須針對每一個定義的關聯性執行一次此預存程序。 如需詳細資訊,請參閱 定義和修改合併發行項之間的聯結篩選

  5. 在發行集資料庫的發行者端,執行 sp_helpmergepublication (Transact-SQL),並指定步驟 1 中的 @publication值。 請注意結果集中 snapshot_jobid 的值。

  6. 將步驟 5 取得之 snapshot_jobid 的值轉換成 uniqueidentifier

  7. msdb 資料庫的發行者端,執行 sp_start_job (Transact-SQL),並為 @job_id 指定步驟 6 中所取得的轉換值。

  8. 在發行集資料庫的發行者端,執行 sp_addmergepartition (Transact-SQL)。 為 @publication 指定步驟 1 中的發行集名稱,並為 @suser_sname (如果 SUSER_SNAME (Transact-SQL) 用於篩選子句) 或是為 @host_name (如果 HOST_NAME (Transact-SQL) 用於篩選子句) 指定用於定義資料分割的值。

  9. 在發行集資料庫的發行者端,執行 sp_adddynamicsnapshot_job (Transact-SQL)。 針對 @publication指定步驟 1 中的發行集名稱、步驟 8 中的 @suser_sname@host_name 的值,以及此作業的排程。 這樣會建立針對指定的資料分割產生參數化快照集的作業。 如需詳細資訊,請參閱 Specify Synchronization Schedules

    注意

    這個作業會使用與步驟 2 中定義的初始快照集作業相同的 Windows 帳戶來執行。 若要移除參數化快照集作業及其相關的資料分割,請執行 sp_dropdynamicsnapshot_job (Transact-SQL)

  10. 在發行集資料庫的發行者上,執行 sp_helpmergepartition (Transact-SQL),指定步驟 1 中 @publication 的值以及步驟 8 中 @suser_sname@host_name 的值。 請注意結果集中 dynamic_snapshot_jobid 的值。

  11. msdb 資料庫的散發者端,執行 sp_start_job (Transact-SQL),並為 @job_id 指定步驟 9 中所取得的值。 這樣會啟動資料分割的參數化快照集作業。

  12. 針對每一個訂閱重複步驟 8-11 來產生分割快照集。

針對每一個資料分割建立發行集及手動建立快照集

  1. 若要建立發行集,請執行 sp_addmergepublication (Transact-SQL)。 如需詳細資訊,請參閱建立發行集

  2. 在發行者端,執行 sp_addpublication_snapshot (Transact-SQL)。 針對 @publication 指定步驟 1 中所使用的發行集名稱,以及針對 @job_login@password指定快照集代理程式執行時所使用的 Windows 認證。 如果代理程式會在連接到發行者時使用 SQL Server 驗證,您也必須為 @publisher_security_mode 指定 0 值,並為 @publisher_login@publisher_password 指定 SQL Server 的登入資訊。 這麼做會為發行集建立快照集代理程式作業。 如需有關產生初始快照集以及為快照集代理程式定義自訂排程的詳細資訊,請參閱< Create and Apply the Initial Snapshot>。

    重要

    當利用遠端散發者來設定發行者時,提供給所有參數的值 (包括 job_loginjob_password) 都會以純文字的方式傳給散發者。 您應該先加密「發行者」及其遠端「散發者」之間的連接,再執行這個預存程序。 如需詳細資訊,請參閱啟用資料庫引擎的加密連線 (SQL Server 組態管理員)

  3. 若要將發行項新增至發行集中,請執行 sp_addmergearticle (Transact-SQL)。 必須針對發行集中的每一個發行項執行一次此預存程序。 在使用參數化篩選時,您必須使用 @subset_filterclause 參數,至少針對一個發行項指定參數化資料列篩選器。 如需詳細資訊,請參閱 針對合併發行項定義及修改參數化資料列篩選

  4. 如果將根據參數化資料列篩選器來篩選其他發行項,請執行 sp_addmergefilter (Transact-SQL) 來定義兩個發行項之間的聯結或邏輯記錄關聯性。 必須針對每一個定義的關聯性執行一次此預存程序。 如需詳細資訊,請參閱 定義和修改合併發行項之間的聯結篩選

  5. 從命令提示字元啟動快照集作業或是執行複寫快照集代理程式,以產生標準快照集結構描述和其他檔案。 如需詳細資訊,請參閱 建立和套用初始快照集

  6. 再次從命令提示字元執行複寫快照集代理程式,以產生大量複製 (.bcp) 檔案,為 -DynamicSnapshotLocation 指定分割快照集的位置,以及指定可定義此資料分割的下列其中一個或兩個屬性:

  7. 針對每一個訂閱重複步驟 6 來產生分割快照集。

  8. 針對每一個訂閱執行合併代理程式,以便在訂閱者上套用初始分割快照集,並指定下列屬性:

    • -Hostname - 如果正在覆寫 HOST_NAME 的實際值,則表示用於定義資料分割的值。

    • -DynamicSnapshotLocation - 此資料分割的動態快照集位置。

注意

如需複寫代理程式之程式設計的詳細資訊,請參閱複寫代理程式可執行檔概念

範例 (Transact-SQL)

這個範例會使用參數化篩選來建立合併式發行集,其中的訂閱者會起始快照集的產生程序。 @job_login@job_password 的值會使用指令碼變數來傳遞。

-- 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

這個範例會使用參數化篩選建立發行集,其中的每一個訂閱者會藉由執行 sp_addmergepartition 來定義其資料分割,並藉由執行 sp_adddynamicsnapshot_job 來建立篩選的快照集作業,傳遞資料分割資訊。 @job_login@job_password 的值會使用指令碼變數來傳遞。

-- 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.  
EXEC sp_addmergepublication 
  @publication = @publication, 
  @description = N'Merge publication of AdventureWorks2022.', 
  @allow_subscriber_initiated_snapshot = N'false';

-- 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 customer 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 snapshot agent job.
DECLARE @publication AS sysname;
SET @publication = N'AdvWorksSalesPersonMerge';

EXEC sp_startpublication_snapshot 
  @publication = @publication;
GO

PRINT '*** Waiting for the initial snapshot.';
GO

-- Create a temporary table to store the filtered data snapshot 
-- job information.
CREATE TABLE #temp (id int,
    job_name sysname,
    job_id uniqueidentifier,
    dynamic_filter_login sysname NULL,
    dynamic_filter_hostname sysname NULL,
    dynamic_snapshot_location nvarchar(255),
    frequency_type int, 
    frequency_interval int, 
    frequency_subday_type int,
    frequency_subday_interval int, 
    frequency_relative_interval int, 
    frequency_recurrence_factor int, 
    active_start_date int, 
    active_end_date int, 
    active_start_time int, 
    active_end_time int
)

-- Create each snapshot for a partition 
-- The initial snapshot must already be generated.
DECLARE @publication AS sysname;
DECLARE @jobname AS sysname
DECLARE @hostname AS sysname
SET @publication = N'AdvWorksSalesPersonMerge';
SET @hostname = N'adventure-works\Fernando';

WHILE NOT EXISTS(SELECT * FROM sysmergepublications 
    WHERE [name] = @publication 
    AND snapshot_ready = 1)
BEGIN
    WAITFOR DELAY '00:00:05'
END

-- Create a data partition by overriding HOST_NAME().
EXEC sp_addmergepartition 
  @publication = @publication,
  @host_name = @hostname;

-- Create the filtered data snapshot job, and use the returned 
-- information to start the job.
EXEC sp_adddynamicsnapshot_job 
  @publication = @publication,
  @host_name = @hostname;

INSERT INTO #temp (id, job_name, job_id, dynamic_filter_login,
    dynamic_filter_hostname, dynamic_snapshot_location,
    frequency_type,	frequency_interval, frequency_subday_type,
    frequency_subday_interval, frequency_relative_interval, 
    frequency_recurrence_factor, active_start_date,	active_end_date, 
    active_start_time,active_end_time)
EXEC sp_helpdynamicsnapshot_job;

SELECT @jobname = (SELECT DISTINCT job_name FROM #temp WHERE dynamic_filter_hostname = @hostname);

EXEC msdb..sp_start_job @job_name = @jobname;
DROP TABLE #temp;
GO

這個範例會使用參數化篩選建立發行集,其中的每一個訂閱者必須藉由提供資料分割資訊,以建立其資料分割和篩選的快照集作業。 訂閱者在手動執行複寫代理程式時,會使用命令列參數提供資料分割資訊。 此範例假設也已經建立發行集的訂閱。

-- 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.  
EXEC sp_addmergepublication 
  @publication = @publication, 
  @description = N'Merge publication of AdventureWorks2022.', 
  @allow_subscriber_initiated_snapshot = N'false';

-- 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 customer 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
  
REM Line breaks are added to improve readability.   
REM In a batch file, commands must be made in a single line.  
REM Run the Snapshot agent from the command line to generate the standard snapshot   
REM schema and other files.   
SET DistPub=%computername%  
SET PubDB=AdventureWorks2022   
SET PubName=AdvWorksSalesPersonMerge  
  
"C:\Program Files\Microsoft SQL Server\120\COM\SNAPSHOT.EXE" -Publication %PubName%    
-Publisher %DistPub% -Distributor  %DistPub%  -PublisherDB %PubDB%  -ReplicationType 2    
-OutputVerboseLevel 1  -DistributorSecurityMode 1  
  
PAUSE  
  
  
REM Run the Snapshot agent from the command line, this time to generate   
REM the bulk copy (.bcp) data for each Subscriber partition.    
SET DistPub=%computername%  
SET PubDB=AdventureWorks2022   
SET PubName=AdvWorksSalesPersonMerge  
SET SnapshotDir=\\%DistPub%\repldata\unc\fernando  
  
MD %SnapshotDir%  
  
"C:\Program Files\Microsoft SQL Server\120\COM\SNAPSHOT.EXE" -Publication %PubName%    
-Publisher %DistPub%  -Distributor  %DistPub%  -PublisherDB %PubDB%  -ReplicationType 2    
-OutputVerboseLevel 1  -DistributorSecurityMode 1  -DynamicFilterHostName "adventure-works\Fernando"    
-DynamicSnapshotLocation %SnapshotDir%  
  
PAUSE  
  
  
REM Run the Merge Agent for each subscription to apply the partitioned   
REM snapshot for each Subscriber.    
SET Publisher = %computername%  
SET Subscriber = %computername%  
SET PubDB = AdventureWorks2022   
SET SubDB = AdventureWorks2022Replica   
SET PubName = AdvWorksSalesPersonMerge   
SET SnapshotDir=\\%DistPub%\repldata\unc\fernando  
  
"C:\Program Files\Microsoft SQL Server\120\COM\REPLMERG.EXE" -Publisher  %Publisher%    
-Subscriber  %Subscriber%  -Distributor %Publisher%  -PublisherDB %PubDB%    
-SubscriberDB %SubDB% -Publication %PubName%  -PublisherSecurityMode 1  -OutputVerboseLevel 3    
-Output -SubscriberSecurityMode 1  -SubscriptionType 3 -DistributorSecurityMode 1    
-Hostname "adventure-works\Fernando"  -DynamicSnapshotLocation %SnapshotDir%  
  
PAUSE  
  

使用 Replication Management Objects (RMO)

您可以透過以下方式,以程式設計的方式使用 Replication Management Objects (RMO) 來產生分割快照集。

  • 允許訂閱者在首次執行同步處理時,要求快照集產生和應用程式。

  • 為每個資料分割預先產生快照集。

  • 執行「快照集代理程式」為每個訂閱者手動產生快照集。

注意

當篩選發行項產生了對每個訂閱而言是唯一的非重疊資料分割時 (在建立合併發行項時,針對 P:Microsoft.SqlServer.Replication.MergeArticle.PartitionOption 指定 F:Microsoft.SqlServer.Replication.PartitionOptions.NonOverlappingSingleSubscription 的值),則只要合併代理程式一執行,就會清除中繼資料。 這表示分割快照集會更快過期。 當使用這個選項時,您應該考慮允許訂閱者要求產生快照集。 如需詳細資訊,請參閱< Parameterized Row Filters>主題中的「使用適當的篩選選項」一節。

重要

可能的話,會在執行階段提示使用者輸入安全性認證。 如果您必須儲存認證,請使用 Microsoft Windows .NET Framework 提供的密碼編譯服務

建立可讓訂閱者初始化快照集產生和傳遞的發行集

  1. 使用 ServerConnection 類別建立與發行者的連接。

  2. 為發行集資料庫建立 ReplicationDatabase 類別的執行個體、將 ConnectionContext 屬性設定為步驟 1 中的 ServerConnection 執行個體,並呼叫 LoadProperties 方法。 If LoadProperties 傳回 false,請確認此資料庫確實存在。

  3. If EnabledMergePublishing 屬性為 false,請將它設定為 \@allow_subscriber_initiated_snapshot 然後呼叫 CommitPropertyChanges

  4. 建立 MergePublication 類別的執行個體,並為此物件設定下列屬性:

  5. 呼叫 Create 方法來建立發行集。

    重要

    當利用遠端散發者來設定發行者時,提供給所有屬性的值 (包括 SnapshotGenerationAgentProcessSecurity) 都會以純文字的方式傳給散發者。 您應該先加密「發行者」及其遠端「散發者」之間的連線,然後再呼叫 Create 方法。 如需詳細資訊,請參閱啟用資料庫引擎的加密連線 (SQL Server 組態管理員)

  6. 使用 MergeArticle 屬性將發行項加入發行集中。 至少針對定義參數化篩選的一個發行項指定 FilterClause 屬性。 (選擇性) 建立可在發行項之間定義聯結篩選的 MergeJoinFilter 物件。 如需詳細資訊,請參閱 定義發行項

  7. 如果 SnapshotAgentExists 的值是 false,請呼叫 CreateSnapshotAgent 來針對這個發行集建立初始快照集代理程式作業。

  8. 呼叫步驟 4 中建立之 StartSnapshotGenerationAgentJob 物件的 MergePublication 方法。 這樣會啟動可產生初始快照集的代理程式作業。 如需有關產生初始快照集以及為快照集代理程式定義自訂排程的詳細資訊,請參閱< Create and Apply the Initial Snapshot>。

  9. (選擇性) 檢查是否有為 \@allow_subscriber_initiated_snapshot 屬性設定 SnapshotAvailable 的值,以判斷初始快照集何時可準備好供人使用。

  10. 當訂閱者的合併代理程式第一次連接時,會自動產生分割快照集。

建立發行集及預先產生或自動重新整理快照集

  1. 使用 MergePublication 類別的執行個體來定義合併式發行集。 如需詳細資訊,請參閱建立發行集

  2. 使用 MergeArticle 屬性將發行項加入發行集中。 至少針對定義參數化篩選的一個發行項指定 FilterClause 屬性,並建立可在兩個發行項之間定義聯結篩選的任何 MergeJoinFilter 物件。 如需詳細資訊,請參閱 定義發行項

  3. 如果 SnapshotAgentExists 的值是 false,請呼叫 CreateSnapshotAgent 來針對這個發行集建立快照集代理程式作業。

  4. 呼叫步驟 1 中建立之 StartSnapshotGenerationAgentJob 物件的 MergePublication 方法。 這個方法會啟動可產生初始快照集的代理程式作業。 如需有關產生初始快照集以及為快照集代理程式定義自訂排程的詳細資訊,請參閱< 建立和套用初始快照集>。

  5. 檢查是否有為 \@allow_subscriber_initiated_snapshot 屬性設定 SnapshotAvailable 的值,以判斷初始快照集何時可準備好供人使用。

  6. 建立 MergePartition 類別的執行個體,並使用以下其中一個或兩個屬性來為訂閱者設定參數化篩選準則:

  7. 建立 MergeDynamicSnapshotJob 類別的執行個體,並設定與步驟 6 中相同的屬性。

  8. 使用 ReplicationAgentSchedule 類別來定義排程,以針對訂閱者資料分割產生篩選的快照集。

  9. 使用步驟 1 中的 MergePublication 執行個體,呼叫 AddMergePartition。 傳遞步驟 6 的 MergePartition 物件。

  10. 使用步驟 1 中的 MergePublication 執行個體,呼叫 AddMergeDynamicSnapshotJob 方法。 傳遞步驟 7 中的 MergeDynamicSnapshotJob 物件及步驟 8 中的 ReplicationAgentSchedule 物件。

  11. 呼叫 EnumMergeDynamicSnapshotJobs並在 MergeDynamicSnapshotJob 物件中找出傳回的陣列中新加入的分割快照集作業。

  12. 取得此作業的 Name 屬性。

  13. 使用 ServerConnection 類別建立與散發者的連接。

  14. 建立 SQL Server 管理物件 (SMO) Server 類別的執行個體,傳遞步驟 13 中的 ServerConnection 物件。

  15. 建立 Job 類別的執行個體,傳遞步驟 14 中 JobServerServer 屬性及步驟 12 中的作業名稱。

  16. 呼叫 Start 方法來啟動分割快照集作業。

  17. 對每一個訂閱者重複步驟 6-16。

針對每一個資料分割建立發行集及手動建立快照集

  1. 使用 MergePublication 類別的執行個體來定義合併式發行集。 如需詳細資訊,請參閱建立發行集

  2. 使用 MergeArticle 屬性將發行項加入發行集中。至少針對定義參數化篩選的一個發行項指定 FilterClause 屬性,並建立可在兩個發行項之間定義聯結篩選的任何 MergeJoinFilter 物件。 如需詳細資訊,請參閱 定義發行項

  3. 產生初始快照集。 如需詳細資訊,請參閱 建立和套用初始快照集

  4. 建立 SnapshotGenerationAgent 類別的執行個體,並設定下列必要的屬性:

  5. Merge 設定 ReplicationType的值。

  6. 設定以下其中一個或多個屬性來定義資料分割參數:

  7. 呼叫 GenerateSnapshot 方法。

  8. 對每一個訂閱者重複步驟 4-7。

範例 (RMO)

此範例會建立允許訂閱者要求產生快照集的合併式發行集。

// Set the Publisher, publication database, and publication names.
string publisherName = publisherInstance;
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorks2022";

ReplicationDatabase publicationDb;
MergePublication publication;

// Create a connection to the Publisher.
ServerConnection conn = new ServerConnection(publisherName);

try
{
    // Connect to the Publisher.
    conn.Connect();

    // Enable the database for merge publication.				
    publicationDb = new ReplicationDatabase(publicationDbName, conn);
    if (publicationDb.LoadProperties())
    {
        if (!publicationDb.EnabledMergePublishing)
        {
            publicationDb.EnabledMergePublishing = true;
        }
    }
    else
    {
        // Do something here if the database does not exist. 
        throw new ApplicationException(String.Format(
            "The {0} database does not exist on {1}.",
            publicationDb, publisherName));
    }

    // Set the required properties for the merge publication.
    publication = new MergePublication();
    publication.ConnectionContext = conn;
    publication.Name = publicationName;
    publication.DatabaseName = publicationDbName;

    // Enable precomputed partitions.
    publication.PartitionGroupsOption = PartitionGroupsOption.True;

    // Specify the Windows account under which the Snapshot Agent job runs.
    // This account will be used for the local connection to the 
    // Distributor and all agent connections that use Windows Authentication.
    publication.SnapshotGenerationAgentProcessSecurity.Login = winLogin;
    publication.SnapshotGenerationAgentProcessSecurity.Password = winPassword;

    // Explicitly set the security mode for the Publisher connection
    // Windows Authentication (the default).
    publication.SnapshotGenerationAgentPublisherSecurity.WindowsAuthentication = true;

    // Enable Subscribers to request snapshot generation and filtering.
    publication.Attributes |= PublicationAttributes.AllowSubscriberInitiatedSnapshot;
    publication.Attributes |= PublicationAttributes.DynamicFilters;

    // Enable pull and push subscriptions.
    publication.Attributes |= PublicationAttributes.AllowPull;
    publication.Attributes |= PublicationAttributes.AllowPush;

    if (!publication.IsExistingObject)
    {
        // Create the merge publication.
        publication.Create();
        
        // Create a Snapshot Agent job for the publication.
        publication.CreateSnapshotAgent();
    }
    else
    {
        throw new ApplicationException(String.Format(
            "The {0} publication already exists.", publicationName));
    }
}

catch (Exception ex)
{
    // Implement custom application error handling here.
    throw new ApplicationException(String.Format(
        "The publication {0} could not be created.", publicationName), ex);
}
finally
{
    conn.Disconnect();
}
' Set the Publisher, publication database, and publication names.
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2022"

Dim publicationDb As ReplicationDatabase
Dim publication As MergePublication

' Create a connection to the Publisher.
Dim conn As ServerConnection = New ServerConnection(publisherName)

Try
    ' Connect to the Publisher.
    conn.Connect()

    ' Enable the database for merge publication.				
    publicationDb = New ReplicationDatabase(publicationDbName, conn)
    If publicationDb.LoadProperties() Then
        If Not publicationDb.EnabledMergePublishing Then
            publicationDb.EnabledMergePublishing = True
        End If
    Else
        ' Do something here if the database does not exist. 
        Throw New ApplicationException(String.Format( _
         "The {0} database does not exist on {1}.", _
         publicationDb, publisherName))
    End If

    ' Set the required properties for the merge publication.
    publication = New MergePublication()
    publication.ConnectionContext = conn
    publication.Name = publicationName
    publication.DatabaseName = publicationDbName

    ' Enable precomputed partitions.
    publication.PartitionGroupsOption = PartitionGroupsOption.True

    ' Specify the Windows account under which the Snapshot Agent job runs.
    ' This account will be used for the local connection to the 
    ' Distributor and all agent connections that use Windows Authentication.
    publication.SnapshotGenerationAgentProcessSecurity.Login = winLogin
    publication.SnapshotGenerationAgentProcessSecurity.Password = winPassword

    ' Explicitly set the security mode for the Publisher connection
    ' Windows Authentication (the default).
    publication.SnapshotGenerationAgentPublisherSecurity.WindowsAuthentication = True

    ' Enable Subscribers to request snapshot generation and filtering.
    publication.Attributes = publication.Attributes Or _
        PublicationAttributes.AllowSubscriberInitiatedSnapshot
    publication.Attributes = publication.Attributes Or _
        PublicationAttributes.DynamicFilters

    ' Enable pull and push subscriptions
    publication.Attributes = publication.Attributes Or _
        PublicationAttributes.AllowPull
    publication.Attributes = publication.Attributes Or _
        PublicationAttributes.AllowPush

    If Not publication.IsExistingObject Then
        ' Create the merge publication.
        publication.Create()

        ' Create a Snapshot Agent job for the publication.
        publication.CreateSnapshotAgent()
    Else
        Throw New ApplicationException(String.Format( _
            "The {0} publication already exists.", publicationName))
    End If
Catch ex As Exception
    ' Implement custom application error handling here.
    Throw New ApplicationException(String.Format( _
        "The publication {0} could not be created.", publicationName), ex)
Finally
    conn.Disconnect()
End Try

這個範例會使用參數化資料列篩選器,針對合併式發行集手動建立訂閱者資料分割及篩選的快照集。

// Define the server, database, and publication names
string publisherName = publisherInstance;
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorks2022";
string distributorName = publisherInstance;

MergePublication publication;
MergePartition partition;
MergeDynamicSnapshotJob snapshotAgentJob;
ReplicationAgentSchedule schedule;

// Create a connection to the Publisher.
ServerConnection publisherConn = new ServerConnection(publisherName);

// Create a connection to the Distributor to start the Snapshot Agent.
ServerConnection distributorConn = new ServerConnection(distributorName);

try
{
    // Connect to the Publisher.
    publisherConn.Connect();

    // Set the required properties for the publication.
    publication = new MergePublication();
    publication.ConnectionContext = publisherConn;
    publication.Name = publicationName;
    publication.DatabaseName = publicationDbName;


    // If we can't get the properties for this merge publication, 
    // then throw an application exception.
    if (publication.LoadProperties() || publication.SnapshotAvailable)
    {
        // Set a weekly schedule for the filtered data snapshot.
        schedule = new ReplicationAgentSchedule();
        schedule.FrequencyType = ScheduleFrequencyType.Weekly;
        schedule.FrequencyRecurrenceFactor = 1;
        schedule.FrequencyInterval = Convert.ToInt32(0x001);

        // Set the value of Hostname that defines the data partition. 
        partition = new MergePartition();
        partition.DynamicFilterHostName = hostname;
        snapshotAgentJob = new MergeDynamicSnapshotJob();
        snapshotAgentJob.DynamicFilterHostName = hostname;

        // Create the partition for the publication with the defined schedule.
        publication.AddMergePartition(partition);
        publication.AddMergeDynamicSnapshotJob(snapshotAgentJob, schedule);
    }
    else
    {
        throw new ApplicationException(String.Format(
            "Settings could not be retrieved for the publication, " +
            " or the initial snapshot has not been generated. " +
            "Ensure that the publication {0} exists on {1} and " +
            "that the Snapshot Agent has run successfully.",
            publicationName, publisherName));
    }
}
catch (Exception ex)
{
    // Do error handling here.
    throw new ApplicationException(string.Format(
        "The partition for '{0}' in the {1} publication could not be created.",
        hostname, publicationName), ex);
}
finally
{
    publisherConn.Disconnect();
    if (distributorConn.IsOpen) distributorConn.Disconnect();
}
' Define the server, database, and publication names
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2022"
Dim distributorName As String = publisherInstance

Dim publication As MergePublication
Dim partition As MergePartition
Dim snapshotAgentJob As MergeDynamicSnapshotJob
Dim schedule As ReplicationAgentSchedule

' Create a connection to the Publisher.
Dim publisherConn As ServerConnection = New ServerConnection(publisherName)

' Create a connection to the Distributor to start the Snapshot Agent.
Dim distributorConn As ServerConnection = New ServerConnection(distributorName)

Try
    ' Connect to the Publisher.
    publisherConn.Connect()

    ' Set the required properties for the publication.
    publication = New MergePublication()
    publication.ConnectionContext = publisherConn
    publication.Name = publicationName
    publication.DatabaseName = publicationDbName


    ' If we can't get the properties for this merge publication, 
    ' then throw an application exception.
    If (publication.LoadProperties() Or publication.SnapshotAvailable) Then
        ' Set a weekly schedule for the filtered data snapshot.
        schedule = New ReplicationAgentSchedule()
        schedule.FrequencyType = ScheduleFrequencyType.Weekly
        schedule.FrequencyRecurrenceFactor = 1
        schedule.FrequencyInterval = Convert.ToInt32("0x001", 16)

        ' Set the value of Hostname that defines the data partition. 
        partition = New MergePartition()
        partition.DynamicFilterHostName = hostname
        snapshotAgentJob = New MergeDynamicSnapshotJob()
        snapshotAgentJob.DynamicFilterHostName = hostname

        ' Create the partition for the publication with the defined schedule.
        publication.AddMergePartition(partition)
        publication.AddMergeDynamicSnapshotJob(snapshotAgentJob, schedule)
    Else
        Throw New ApplicationException(String.Format( _
         "Settings could not be retrieved for the publication, " + _
         " or the initial snapshot has not been generated. " + _
         "Ensure that the publication {0} exists on {1} and " + _
         "that the Snapshot Agent has run successfully.", _
         publicationName, publisherName))
    End If
Catch ex As Exception
    ' Do error handling here.
    Throw New ApplicationException(String.Format( _
     "The partition for '{0}' in the {1} publication could not be created.", _
     hostname, publicationName), ex)
Finally
    publisherConn.Disconnect()
    If distributorConn.IsOpen Then
        distributorConn.Disconnect()
    End If
End Try

這個範例會使用參數化資料列篩選器,針對合併式發行集的訂閱者啟動快照集代理程式來產生篩選的資料快照集。

// Set the Publisher, publication database, and publication names.
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorks2022";
string publisherName = publisherInstance;
string distributorName = publisherInstance;

SnapshotGenerationAgent agent;

try
{
    // Set the required properties for Snapshot Agent.
    agent = new SnapshotGenerationAgent();
    agent.Distributor = distributorName;
    agent.DistributorSecurityMode = SecurityMode.Integrated;
    agent.Publisher = publisherName;
    agent.PublisherSecurityMode = SecurityMode.Integrated;
    agent.Publication = publicationName;
    agent.PublisherDatabase = publicationDbName;
    agent.ReplicationType = ReplicationType.Merge;

    // Specify the partition information to generate a 
    // filtered snapshot based on Hostname.
    agent.DynamicFilterHostName = hostname;

    // Start the agent synchronously.
    agent.GenerateSnapshot();
}
catch (Exception ex)
{
    // Implement custom application error handling here.
    throw new ApplicationException(String.Format(
        "A snapshot could not be generated for the {0} publication."
        , publicationName), ex);
}
' Set the Publisher, publication database, and publication names.
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2022"
Dim publisherName As String = publisherInstance
Dim distributorName As String = publisherInstance

Dim agent As SnapshotGenerationAgent

Try
    ' Set the required properties for Snapshot Agent.
    agent = New SnapshotGenerationAgent()
    agent.Distributor = distributorName
    agent.DistributorSecurityMode = SecurityMode.Integrated
    agent.Publisher = publisherName
    agent.PublisherSecurityMode = SecurityMode.Integrated
    agent.Publication = publicationName
    agent.PublisherDatabase = publicationDbName
    agent.ReplicationType = ReplicationType.Merge

    ' Specify the partition information to generate a 
    ' filtered snapshot based on Hostname.
    agent.DynamicFilterHostName = hostname

    ' Start the agent synchronously.
    agent.GenerateSnapshot()
Catch ex As Exception
    ' Implement custom application error handling here.
    Throw New ApplicationException(String.Format( _
     "A snapshot could not be generated for the {0} publication." _
     , publicationName), ex)
End Try

另請參閱

參數化資料列篩選器
Replication System Stored Procedures Concepts
複寫安全性最佳作法