本主題描述如何使用 SQL Server Management Studio、Transact-SQL 或 Replication Management Objects (RMO) 在 SQL Server 2014 中定義文章。
本主題內容
開始之前:
若要定義一篇文章,請使用:
開始之前
限制與制約
- 發行項名稱不能包含下列任何字元:% 、 * 、 [ 、 ] 、 |, : , " , ? 、' 、 \ 、 / 、 < 、 >。 如果資料庫中的物件包含上述任何字元,而且您想要復寫這些字元,您必須指定與物件名稱不同的發行項名稱。
安全
可能的話,會在執行階段提示使用者輸入安全性認證。 如果您必須儲存認證,請使用 Microsoft Windows .NET Framework 提供的密碼編譯服務。
使用 SQL Server Management Studio
使用 [新增發行集精靈] 建立發行集並定義文章。 建立發行集之後,請在 [ 發行集屬性 - <發行集] 對話框中檢視和修改發行集> 屬性。 如需從 Oracle 資料庫建立發行集的詳細資訊,請參閱 從 Oracle 資料庫建立發行集。
建立出版物並定義文章
在 Microsoft SQL Server Management Studio 中連接到發行者,然後展開伺服器節點。
展開 複寫 資料夾,然後滑鼠右鍵點擊 本機發行集 資料夾。
點擊新發行。
請按照「新出版物精靈」中的頁面,進行下列操作:
如果未在伺服器上設定散發,請指定散發者。 若要取得設定分發的詳細資訊,請參閱 設定發佈和分發。
如果您在 [散發者] 頁面上指定發行者伺服器將作為自己的散發者(本機散發者),但伺服器尚未設定為「散發者」,[新增發行集精靈] 會為您設定伺服器。 您將在 [快照資料夾] 頁面上指定散發者的預設快照資料夾。 快照集資料夾只是您指定為共享的目錄;讀取和寫入此資料夾的代理程式必須有足夠的許可權才能存取它。 如需適當保護資料夾的詳細資訊,請參閱 保護快照集資料夾。
如果您指定另一部伺服器應該做為「散發者」,您必須在 [ 系統管理密碼 ] 頁面上輸入密碼,以取得從發行者到散發者的連線。 此密碼必須符合在遠端散發者端啟用發行者時所指定的密碼。
如需詳細資訊,請參閱 配置發佈。
選擇出版資料庫。
選取發行集類型。 如需詳細資訊,請參閱 複寫類型。
指定要發佈的數據和資料庫物件;選擇性地篩選數據表發行項中的數據行,並設定發行項屬性。
可以選擇篩選資料表中的資料列。 如需詳細資訊,請參閱 篩選已發佈的數據。
設定快照代理程式排程。
指定執行下列複寫代理程式並建立連線所需的認證:
- 所有發行項目的快照代理程式。
- 用於所有事務性發行集的記錄讀取器代理程式。
- 用於允許更新訂閱的交易式發行集的佇列讀取器代理程式。
如需詳細資訊,請參閱 複寫代理程式安全性模型 和 復寫安全性最佳做法。
選擇性地編寫發佈腳本。 如需詳細資訊,請參閱 Scripting Replication。
指定出版物的名稱。
使用 Transact-SQL
建立發行集之後,可以使用複製儲存過程以程式化方式建立文章。 用來建立文章的預存程式將取決於該文章所屬的出版類型。 如需詳細資訊,請參閱建立出版物。
定義快照式或交易式發行集的發行項
在發行集資料庫的發行者上,執行 sp_addarticle。 針對 @publication 指定文章所屬刊物的名稱、@article 文章的名稱、針對 @source_object 正在出版的資料庫物件,以及任何其他選擇性參數。 如果不是 dbo,請使用@source_owner來指定對象的架構擁有權。 如果發行項不是以記錄為基礎的數據表發行項,請指定@type的發行項類型;如需詳細資訊,請參閱指定發行項類型(複寫 Transact-SQL 程序設計)。
若要水平篩選表格或檢視中的資料列,請使用 sp_articlefilter 來定義篩選子句。 如需詳細資訊,請參閱 定義和修改靜態數據列篩選。
若要對資料表中的欄位或檢視文章進行垂直篩選,請使用 sp_articlecolumn。 如需詳細資訊,請參閱 定義和修改數據行篩選。
如果文章有被篩選,請執行sp_articleview。
如果發行集有現有的訂閱,且sp_helppublication在immediate_sync列中傳回值0,您必須呼叫sp_addsubscription,將文章新增至每個現有的訂閱。
如果發行項目有現有的提取訂閱,請在發行者端執行 sp_refreshsubscriptions ,為現有的提取訂閱建立只包含新文章的新快照。
備註
對於未使用快照集初始化的訂用帳戶,您不需要執行 sp_refreshsubscriptions ,因為此程式是由 sp_addarticle 執行。
定義合併出版物的文章
在發行集資料庫的發行者上,執行 sp_addmergearticle。 指定 @publication 的出版物名稱、@article 的文章名稱,以及 @source_object 的發布對象。 若要水平篩選數據表數據列,請指定 @subset_filterclause的值。 如需詳細資訊,請參閱 定義和修改合併發行項的參數化數據列篩選 和 定義及修改靜態數據列篩選。 如果發行項不是數據表發行項,請指定 @type的發行項類型。 如需詳細資訊,請參閱指定文章類型(複寫程式設計 Transact-SQL)。
(選擇性)在發行資料庫的發行者上,執行 sp_addmergefilter 以定義兩個資料項之間的聯結篩選。 如需詳細資訊,請參閱 定義和修改合併發行項之間的聯結篩選。
(選擇性)在發行集資料庫的發布者上,執行 sp_mergearticlecolumn 來篩選表格欄位。 如需詳細資訊,請參閱 定義和修改數據行篩選。
範例 (Transact-SQL)
此範例會根據交易式發行物中的 Product 表格定義文章,並水平和垂直進行篩選。
DECLARE @publication AS sysname;
DECLARE @table AS sysname;
DECLARE @filterclause AS nvarchar(500);
DECLARE @filtername AS nvarchar(386);
DECLARE @schemaowner AS sysname;
SET @publication = N'AdvWorksProductTran';
SET @table = N'Product';
SET @filterclause = N'[DiscontinuedDate] IS NULL';
SET @filtername = N'filter_out_discontinued';
SET @schemaowner = N'Production';
-- Add a horizontally and vertically filtered article for the Product table.
-- Manually set @schema_option to ensure that the Production schema
-- is generated at the Subscriber (0x8000000).
EXEC sp_addarticle
@publication = @publication,
@article = @table,
@source_object = @table,
@source_owner = @schemaowner,
@schema_option = 0x80030F3,
@vertical_partition = N'true',
@type = N'logbased',
@filter_clause = @filterclause;
-- (Optional) Manually call the stored procedure to create the
-- horizontal filtering stored procedure. Since the type is
-- 'logbased', this stored procedures is executed automatically.
EXEC sp_articlefilter
@publication = @publication,
@article = @table,
@filter_clause = @filterclause,
@filter_name = @filtername;
-- Add all columns to the article.
EXEC sp_articlecolumn
@publication = @publication,
@article = @table;
-- Remove the DaysToManufacture column from the article
EXEC sp_articlecolumn
@publication = @publication,
@article = @table,
@column = N'DaysToManufacture',
@operation = N'drop';
-- (Optional) Manually call the stored procedure to create the
-- vertical filtering view. Since the type is 'logbased',
-- this stored procedures is executed automatically.
EXEC sp_articleview
@publication = @publication,
@article = @table,
@filter_clause = @filterclause;
GO
此範例會定義合併出版物的文章,其中 SalesOrderHeader 文章會根據 SalesPersonID 以靜態方式篩選,而 SalesOrderDetail 文章會根據 SalesOrderHeader以連接方式篩選。
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
使用 Replication Management Objects (RMO)
您可以使用複寫管理物件 (RMO) 以程式設計方式定義發行項。 您用來定義發行項的 RMO 類別取決於定義發行項的發行集類型。
範例 (RMO)
下列範例會將帶有欄和列篩選器的文章新增至交易式發行。
// Define the Publisher, publication, and article names.
string publisherName = publisherInstance;
string publicationName = "AdvWorksProductTran";
string publicationDbName = "AdventureWorks2012";
string articleName = "Product";
string schemaOwner = "Production";
TransArticle article;
// Create a connection to the Publisher.
ServerConnection conn = new ServerConnection(publisherName);
// Create a filtered transactional articles in the following steps:
// 1) Create the article with a horizontal filter clause.
// 2) Add columns to or remove columns from the article.
try
{
// Connect to the Publisher.
conn.Connect();
// Define a horizontally filtered, log-based table article.
article = new TransArticle();
article.ConnectionContext = conn;
article.Name = articleName;
article.DatabaseName = publicationDbName;
article.SourceObjectName = articleName;
article.SourceObjectOwner = schemaOwner;
article.PublicationName = publicationName;
article.Type = ArticleOptions.LogBased;
article.FilterClause = "DiscontinuedDate IS NULL";
// Ensure that we create the schema owner at the Subscriber.
article.SchemaOption |= CreationScriptOptions.Schema;
if (!article.IsExistingObject)
{
// Create the article.
article.Create();
}
else
{
throw new ApplicationException(String.Format(
"The article {0} already exists in publication {1}.",
articleName, publicationName));
}
// Create an array of column names to remove from the article.
String[] columns = new String[1];
columns[0] = "DaysToManufacture";
// Remove the column from the article.
article.RemoveReplicatedColumns(columns);
}
catch (Exception ex)
{
// Implement appropriate error handling here.
throw new ApplicationException("The article could not be created.", ex);
}
finally
{
conn.Disconnect();
}
' Define the Publisher, publication, and article names.
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksProductTran"
Dim publicationDbName As String = "AdventureWorks2012"
Dim articleName As String = "Product"
Dim schemaOwner As String = "Production"
Dim article As TransArticle
' Create a connection to the Publisher.
Dim conn As ServerConnection = New ServerConnection(publisherName)
' Create a filtered transactional articles in the following steps:
' 1) Create the article with a horizontal filter clause.
' 2) Add columns to or remove columns from the article.
Try
' Connect to the Publisher.
conn.Connect()
' Define a horizontally filtered, log-based table article.
article = New TransArticle()
article.ConnectionContext = conn
article.Name = articleName
article.DatabaseName = publicationDbName
article.SourceObjectName = articleName
article.SourceObjectOwner = schemaOwner
article.PublicationName = publicationName
article.Type = ArticleOptions.LogBased
article.FilterClause = "DiscontinuedDate IS NULL"
' Ensure that we create the schema owner at the Subscriber.
article.SchemaOption = article.SchemaOption Or _
CreationScriptOptions.Schema
If Not article.IsExistingObject Then
' Create the article.
article.Create()
Else
Throw New ApplicationException(String.Format( _
"The article {0} already exists in publication {1}.", _
articleName, publicationName))
End If
' Create an array of column names to remove from the article.
Dim columns() As String = New String(0) {}
columns(0) = "DaysToManufacture"
' Remove the column from the article.
article.RemoveReplicatedColumns(columns)
Catch ex As Exception
' Implement appropriate error handling here.
Throw New ApplicationException("The article could not be created.", ex)
Finally
conn.Disconnect()
End Try
下列範例會將三篇文章新增至合併式發行集。 發行項具有數據行篩選,而兩個聯結篩選可用來將參數化數據列篩選傳播至其他發行項。
// Define the Publisher and publication names.
string publisherName = publisherInstance;
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorks2012";
// Specify article names.
string articleName1 = "Employee";
string articleName2 = "SalesOrderHeader";
string articleName3 = "SalesOrderDetail";
// Specify join filter information.
string filterName12 = "SalesOrderHeader_Employee";
string filterClause12 = "Employee.EmployeeID = " +
"SalesOrderHeader.SalesPersonID";
string filterName23 = "SalesOrderDetail_SalesOrderHeader";
string filterClause23 = "SalesOrderHeader.SalesOrderID = " +
"SalesOrderDetail.SalesOrderID";
string salesSchema = "Sales";
string hrSchema = "HumanResources";
MergeArticle article1 = new MergeArticle();
MergeArticle article2 = new MergeArticle();
MergeArticle article3 = new MergeArticle();
MergeJoinFilter filter12 = new MergeJoinFilter();
MergeJoinFilter filter23 = new MergeJoinFilter();
// Create a connection to the Publisher.
ServerConnection conn = new ServerConnection(publisherName);
// Create three merge articles that are horizontally partitioned
// using a parameterized row filter on Employee.EmployeeID, which is
// extended to the two other articles using join filters.
try
{
// Connect to the Publisher.
conn.Connect();
// Create each article.
// For clarity, each article is defined separately.
// In practice, iterative structures and arrays should
// be used to efficiently create multiple articles.
// Set the required properties for the Employee article.
article1.ConnectionContext = conn;
article1.Name = articleName1;
article1.DatabaseName = publicationDbName;
article1.SourceObjectName = articleName1;
article1.SourceObjectOwner = hrSchema;
article1.PublicationName = publicationName;
article1.Type = ArticleOptions.TableBased;
// Define the parameterized filter clause based on Hostname.
article1.FilterClause = "Employee.LoginID = HOST_NAME()";
// Set the required properties for the SalesOrderHeader article.
article2.ConnectionContext = conn;
article2.Name = articleName2;
article2.DatabaseName = publicationDbName;
article2.SourceObjectName = articleName2;
article2.SourceObjectOwner = salesSchema;
article2.PublicationName = publicationName;
article2.Type = ArticleOptions.TableBased;
// Set the required properties for the SalesOrderDetail article.
article3.ConnectionContext = conn;
article3.Name = articleName3;
article3.DatabaseName = publicationDbName;
article3.SourceObjectName = articleName3;
article3.SourceObjectOwner = salesSchema;
article3.PublicationName = publicationName;
article3.Type = ArticleOptions.TableBased;
if (!article1.IsExistingObject) article1.Create();
if (!article2.IsExistingObject) article2.Create();
if (!article3.IsExistingObject) article3.Create();
// Select published columns for SalesOrderHeader.
// Create an array of column names to vertically filter out.
// In this example, only one column is removed.
String[] columns = new String[1];
columns[0] = "CreditCardApprovalCode";
// Remove the column.
article2.RemoveReplicatedColumns(columns);
// Define a merge filter clauses that filter
// SalesOrderHeader based on Employee and
// SalesOrderDetail based on SalesOrderHeader.
// Parent article.
filter12.JoinArticleName = articleName1;
// Child article.
filter12.ArticleName = articleName2;
filter12.FilterName = filterName12;
filter12.JoinUniqueKey = true;
filter12.FilterTypes = FilterTypes.JoinFilter;
filter12.JoinFilterClause = filterClause12;
// Add the join filter to the child article.
article2.AddMergeJoinFilter(filter12);
// Parent article.
filter23.JoinArticleName = articleName2;
// Child article.
filter23.ArticleName = articleName3;
filter23.FilterName = filterName23;
filter23.JoinUniqueKey = true;
filter23.FilterTypes = FilterTypes.JoinFilter;
filter23.JoinFilterClause = filterClause23;
// Add the join filter to the child article.
article3.AddMergeJoinFilter(filter23);
}
catch (Exception ex)
{
// Do error handling here and rollback the transaction.
throw new ApplicationException(
"The filtered articles could not be created", ex);
}
finally
{
conn.Disconnect();
}
' Define the Publisher and publication names.
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2012"
' Specify article names.
Dim articleName1 As String = "Employee"
Dim articleName2 As String = "SalesOrderHeader"
Dim articleName3 As String = "SalesOrderDetail"
' Specify join filter information.
Dim filterName12 As String = "SalesOrderHeader_Employee"
Dim filterClause12 As String = "Employee.EmployeeID = " + _
"SalesOrderHeader.SalesPersonID"
Dim filterName23 As String = "SalesOrderDetail_SalesOrderHeader"
Dim filterClause23 As String = "SalesOrderHeader.SalesOrderID = " + _
"SalesOrderDetail.SalesOrderID"
Dim salesSchema As String = "Sales"
Dim hrSchema As String = "HumanResources"
Dim article1 As MergeArticle = New MergeArticle()
Dim article2 As MergeArticle = New MergeArticle()
Dim article3 As MergeArticle = New MergeArticle()
Dim filter12 As MergeJoinFilter = New MergeJoinFilter()
Dim filter23 As MergeJoinFilter = New MergeJoinFilter()
' Create a connection to the Publisher.
Dim conn As ServerConnection = New ServerConnection(publisherName)
' Create three merge articles that are horizontally partitioned
' using a parameterized row filter on Employee.EmployeeID, which is
' extended to the two other articles using join filters.
Try
' Connect to the Publisher.
conn.Connect()
' Create each article.
' For clarity, each article is defined separately.
' In practice, iterative structures and arrays should
' be used to efficiently create multiple articles.
' Set the required properties for the Employee article.
article1.ConnectionContext = conn
article1.Name = articleName1
article1.DatabaseName = publicationDbName
article1.SourceObjectName = articleName1
article1.SourceObjectOwner = hrSchema
article1.PublicationName = publicationName
article1.Type = ArticleOptions.TableBased
' Define the parameterized filter clause based on Hostname.
article1.FilterClause = "Employee.LoginID = HOST_NAME()"
' Set the required properties for the SalesOrderHeader article.
article2.ConnectionContext = conn
article2.Name = articleName2
article2.DatabaseName = publicationDbName
article2.SourceObjectName = articleName2
article2.SourceObjectOwner = salesSchema
article2.PublicationName = publicationName
article2.Type = ArticleOptions.TableBased
' Set the required properties for the SalesOrderDetail article.
article3.ConnectionContext = conn
article3.Name = articleName3
article3.DatabaseName = publicationDbName
article3.SourceObjectName = articleName3
article3.SourceObjectOwner = salesSchema
article3.PublicationName = publicationName
article3.Type = ArticleOptions.TableBased
' Create the articles, if they do not already exist.
If article1.IsExistingObject = False Then
article1.Create()
End If
If article2.IsExistingObject = False Then
article2.Create()
End If
If article3.IsExistingObject = False Then
article3.Create()
End If
' Select published columns for SalesOrderHeader.
' Create an array of column names to vertically filter out.
' In this example, only one column is removed.
Dim columns() As String = New String(0) {}
columns(0) = "CreditCardApprovalCode"
' Remove the column.
article2.RemoveReplicatedColumns(columns)
' Define a merge filter clauses that filter
' SalesOrderHeader based on Employee and
' SalesOrderDetail based on SalesOrderHeader.
' Parent article.
filter12.JoinArticleName = articleName1
' Child article.
filter12.ArticleName = articleName2
filter12.FilterName = filterName12
filter12.JoinUniqueKey = True
filter12.FilterTypes = FilterTypes.JoinFilter
filter12.JoinFilterClause = filterClause12
' Add the join filter to the child article.
article2.AddMergeJoinFilter(filter12)
' Parent article.
filter23.JoinArticleName = articleName2
' Child article.
filter23.ArticleName = articleName3
filter23.FilterName = filterName23
filter23.JoinUniqueKey = True
filter23.FilterTypes = FilterTypes.JoinFilter
filter23.JoinFilterClause = filterClause23
' Add the join filter to the child article.
article3.AddMergeJoinFilter(filter23)
Catch ex As Exception
' Do error handling here and rollback the transaction.
Throw New ApplicationException( _
"The filtered articles could not be created", ex)
Finally
conn.Disconnect()
End Try
另請參閱
創建出版物
復寫系統預存程式概念
將發行項新增至現有發行集,並從現有發行集卸除發行項
篩選已發佈的數據
發行資料和資料庫物件
復寫系統預存程式概念