Определение статьи
В данном разделе описывается определение статьи в SQL Server 2012 с помощью среды Среда SQL Server Management Studio, Transact-SQL или объектов RMO.
В этом разделе
Перед началом работы выполните следующие действия.
Ограничения
Безопасность
Для определения статьи используется:
Среда SQL Server Management Studio
Transact-SQL
объекты RMO;
Перед началом
Ограничения
- Названия статей не могут содержать следующие символы: % , * , [ , ] , | , : , " , ? , ' , \ , / , < , >. Если объекты в базе данных, содержащие любые из этих символов, нужно реплицировать, необходимо задать для статьи имя, отличное от имени объекта.
[Top]
Безопасность
По возможности предлагайте пользователям вводить учетные данные безопасности во время выполнения приложения. Если необходимо хранить учетные данные, используйте службы шифрования, предоставляемые платформой Microsoft Windows .NET Framework.
[Top]
Использование среды SQL Server Management Studio
Создание публикаций и определение статей осуществляется с помощью мастера создания публикаций. После создания публикации ее свойства можно просмотреть и изменить в диалоговом окне Свойства публикации — <публикация>. Сведения о создании публикации из базы данных Oracle см. в разделе Создание публикации из базы данных Oracle.
Создание публикации и определение статей
Подключитесь к издателю в среде Microsoft Среда SQL Server Management Studio и разверните узел сервера.
Раскройте папку Репликация, а затем щелкните правой кнопкой мыши папку Локальные публикации.
Щелкните Создать публикацию.
Следуйте указаниям на страницах мастера создания публикаций, чтобы:
задать распространитель, если распространение не было настроено на сервере. Дополнительные сведения о настройке распространения см. в разделе Настройка публикации и распространения.
Если на странице Распространитель вы задаете, что сервер издателя буде функционировать как свой собственный распространитель (локальный распространитель), а сервер не настроен в качестве распространителя, то мастер создания публикаций произведет настройку сервера. Нужно будет задать для распространителя папку моментальных снимков по умолчанию на странице Папка моментальных снимков. Папка моментальных снимков — это просто каталог, назначенный общим ресурсом. Агенты, считывающие и записывающие данные в эту папку, должны иметь необходимые разрешения на нее. Дополнительные сведения о надлежащей защите папок см. в разделе Организация безопасности папки моментальных снимков.
Если задано, что в качестве распространителя будет функционировать другой сервер, необходимо ввести пароль на странице Административный пароль для соединений, устанавливаемых между издателем и распространителем. Этот пароль должен совпадать с паролем, указанным при включении издателя на удаленном распространителе.
Дополнительные сведения см. в разделе Настройка распространителя.
Выберите базу данных публикации.
Выберите тип публикации. Дополнительные сведения см. в разделе Типы репликации.
Задайте данные и объекты базы данных для публикации. При необходимости отфильтруйте столбцы из статей таблиц и установите свойства статей.
Если требуется, отфильтруйте строки из статей таблиц. Дополнительные сведения см. в разделе Фильтрация опубликованных данных.
Настройте расписание для агента моментальных снимков.
Задайте учетные данные, под которыми следующие агенты репликации будут запускаться и устанавливать соединения:
- агент моментальных снимков для всех публикаций
- агент чтения журнала для всех публикаций транзакций
- агент чтения очереди для публикаций транзакций, допускающих обновляемые подписки.
Дополнительные сведения см. в разделах Модель безопасности агента репликации и Рекомендации по защите репликации.
При необходимости создайте скрипт для публикации. Дополнительные сведения см. в разделе Создание сценариев репликации.
Задайте имя для публикации.
[Top]
Использование Transact-SQL
После создания публикации статьи можно создавать программно с помощью хранимых процедур репликации. Конкретные хранимые процедуры, применяемые для создания статей, будут зависеть от типа публикации, для которого определена статья. Дополнительные сведения см. в разделе Создание публикации.
Определение статьи для публикации транзакций или моментальных снимков
Выполните процедуру sp_addarticle на издателе в базе данных публикации. Укажите имя публикации, которой принадлежит статья, в качестве значения параметра @publication, имя статьи в качестве значения параметра @article, публикуемый объект базы данных в качестве значения параметра @source_object, а также, при необходимости, другие параметры. С помощью параметра @source_owner задайте принадлежность схемы объекта. Если она отсутствует, то dbo. Если статья не является статьей таблицы, основанной на журнале, укажите тип статьи в качестве значения параметра @type. Дополнительные сведения см. в разделе задать типы статей (программирование репликации на языке Transact-SQL).
Для горизонтальной фильтрации строк в таблице или для просмотра статьи используйте хранимую процедуру sp_articlefilter, определяющую предложение фильтра. Дополнительные сведения см. в разделе Определение и изменение статического строкового фильтра.
Для вертикальной фильтрации столбцов в таблице или просмотра статьи используйте хранимую процедуру sp_articlecolumn. Дополнительные сведения см. в разделе Определение или изменение фильтра столбцов.
Если статья является фильтруемой, выполните хранимую процедуру sp_articleview.
Если публикация содержит существующие подписки и хранимая процедура sp_helppublication возвращает значение 0 в столбце immediate_sync, то необходимо с помощью хранимой процедуры 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
[Top]
При помощи объектов 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
[Top]
См. также
Основные понятия
Основные понятия системных хранимых процедур репликации
Добавление и удаление статей в существующих публикациях
Фильтрация опубликованных данных