適用於:SQL Server
本文說明如何使用 SQL Server Management Studio、Transact-SQL 或複寫管理物件(RMO)來定義 SQL Server 中的文章。
本文內容
開始之前:
要定義一篇文章,請使用:
開始之前
限制事項
- 文章名稱不得包含以下任何字元:%、* 、[ 、 ] 、|, : , " , ? , ' , \ , / , < , >. 如果資料庫中的物件包含這些字元,且你想複製它們,必須指定一個與物件名稱不同的文章名稱。
安全性
可能的話,會在執行階段提示使用者輸入安全性認證。 如果您必須儲存認證,請使用 Microsoft Windows .NET Framework 提供的密碼編譯服務。
使用 SQL Server Management Studio
使用 新發表精靈 建立出版物並定義文章。 建立出版品後,請在 「出版屬性 - <出版」> 對話框中檢視並修改出版屬性。 如需從 Oracle 資料庫建立發行集的詳細資訊,請參閱從 Oracle 資料庫建立發行集。
建立發佈並定義文章
在 Microsoft SQL Server Management Studio 中連線到發行者,然後展開伺服器節點。
展開 [複寫] 資料夾,然後以滑鼠右鍵按一下 [本機發行集] 資料夾。
按一下 新增出版項目。
請依照 新發佈精靈 中的各個頁面操作:
如果你沒有在伺服器上設定分配,請指定一個分發器。 如需有關設定發佈與散發的詳細資訊,請參閱 設定發佈與散發。
如果您在 Distributor 頁面上指定 Publisher 伺服器充當自己的 Distributor(本機 Distributor),且該伺服器尚未設定為 Distributor,新增發行精靈會設定該伺服器。 你可以在 快照資料夾 頁面指定發行商的預設快照資料夾。 快照資料夾是一個你指定為共享資料夾的目錄。 讀取和寫入此資料夾的代理程式必須擁有足夠的權限才能存取。 如需適當地保護資料夾的詳細資訊,請參閱保護快照集資料夾。
如果你指定另一台伺服器作為分發者,請在管理密碼頁面輸入密碼,以設定從 Publisher 到分發者的連線密碼。 此密碼必須與你啟用遠端發行商 Publisher 時指定的密碼相符。
如需詳細資訊,請參閱 Configure Distribution>。
選擇發佈資料庫。
選取發行集類型。 如需詳細資訊,請參閱複寫類型。
指定要發佈的資料和資料庫物件。 可選擇性地,從表格文章中篩選欄位,並設定文章屬性。
從資料表發行項中選擇性地篩選資料列。 如需更多資訊,請參閱篩選已發佈的資料。
設定「快照代理程式」的排程。
指定下列複寫代理程式在執行及進行連線時所使用的認證:
- 所有發行項目的快照代理程式。
- 所有交易式發行集的記錄讀取器代理程式。
- 適用於允許更新訂閱之交易式發行的佇列讀取器代理程式。
如需相關資訊,請參閱 Replication Agent Security Model 以及 Replication Security Best Practices。
可選擇為發布作業編寫指令碼。 如需詳細資訊,請參閱 Scripting Replication。
請指定出版物的名稱。
使用 TRANSACT-SQL
建立出版品後,利用複製儲存程序以程式化方式建立文章。 建立文章的儲存程序取決於文章的出版類型。 如需更多資訊,請參閱建立出版項目。
為快照式或交易式發行集定義發行項
在發行者上的發行資料庫中,執行 sp_addarticle。 請指定該文章所屬
@publication的出版品名稱、@article文章名稱、你要發表的@source_object資料庫物件名稱,以及其他可選參數。 使用@source_owner來指定此物件的結構描述擁有權 (如果不是 dbo。 如果該文章不是基於日誌的表格文章,請指定該@type文章的文章類型。 如需詳細資訊,請參閱指定發行項類型 (複寫 Transact-SQL 程式設計)。若要以水平方式篩選資料表中的資料列或是檢視發行項,請使用 sp_articlefilter 來定義篩選子句。 如需詳細資訊,請參閱 Define and Modify a Static Row Filter。
若要以垂直方式篩選資料表中的資料行或是檢視發行項,請使用 sp_articlecolumn。 如需詳細資訊,請參閱 Define and Modify a Column Filter。
如果發行項已經過篩選,請執行 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 ,以篩選資料表資料行。 如需詳細資訊,請參閱 Define and Modify a Column Filter。
範例 (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
使用複寫管理物件 (RMO)
您可以使用 Replication Management Objects (RMO) 以程式設計方式定義發行項。 用於定義發行項的 RMO 類別,將取決於定義發行項的發行集類型而定。
範例 (RMO)
下列範例會將具有資料列篩選和資料行篩選的發行項加入交易式發行集中。
// Define the Publisher, publication, and article names.
string publisherName = publisherInstance;
string publicationName = "AdvWorksProductTran";
string publicationDbName = "AdventureWorks2022";
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 = "AdventureWorks2022"
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 = "AdventureWorks2022";
// 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 = "AdventureWorks2022"
' 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