パラメータ化されたフィルタを使用してマージ パブリケーションのスナップショットを作成する方法 (RMO プログラミング)

パラメータ化されたフィルタを使ってマージ パブリケーションのスナップショットを生成する場合は、まず、そのサブスクリプションのサブスクライバ メタデータをすべて含んだ標準 (スキーマ) スナップショットを生成する必要があります。サブスクライバに固有のパーティションのパブリッシュ データだけを含んだ部分的なスナップショットはその後で生成します。詳細については、「初期スナップショットを作成する方法 (RMO プログラミング)」を参照してください。

パーティション スナップショットは、プログラムからレプリケーション管理オブジェクト (RMO) を使用して生成できます。その方法を次に示します。

  • サブスクライバが最初に同期するときに、スナップショットの生成と適用を要求できます。
  • 各パーティションのスナップショットを事前に生成できます。
  • スナップショット エージェントを実行してサブスクライバごとにスナップショットを手動で生成できます。
ms147336.note(ja-jp,SQL.90).gifメモ :
アーティクルをフィルタ選択して、サブスクリプションごとに一意の重複しないパーティションを取得する場合 (マージ アーティクルの作成時、PartitionOption の値に NonOverlappingSingleSubscription を指定した場合)、マージ エージェントの実行時に常にメタデータがクリーンアップされます。これは、パーティション スナップショットの有効期間が短時間で切れてしまうことを意味します。このオプションを使用する場合は、サブスクライバからスナップショットの生成を要求できるようにする必要があります。詳細については、「パラメータ化された行フィルタ」の「適切なフィルタ選択オプションの使用」を参照してください。
ms147336.security(ja-jp,SQL.90).gifセキュリティ メモ :
可能であれば、実行時に、ユーザーに対してセキュリティ資格情報の入力を求めるメッセージを表示します。資格情報を保存する必要がある場合は、Microsoft Windows .NET Framework に用意されている暗号化サービスを使用します。

サブスクライバでスナップショットの生成と配信を開始するためのパブリケーションを作成するには

  1. ServerConnection クラスを使用して、パブリッシャへの接続を作成します。

  2. パブリケーション データベースに ReplicationDatabase クラスのインスタンスを作成するには、ConnectionContext プロパティに手順 1. の ServerConnection インスタンスを設定し、LoadProperties メソッドを呼び出します。LoadProperties から false が返された場合は、データベースが存在していることを確認してください。

  3. EnabledMergePublishing プロパティが false の場合は、このプロパティに true を設定して、CommitPropertyChanges を呼び出します。

  4. MergePublication クラスのインスタンスを作成し、このオブジェクトに次のプロパティを設定します。

    • 手順 1. の ServerConnectionConnectionContext に指定します。
    • パブリッシュするデータベースの名前を DatabaseName に指定します。
    • Name にパブリケーションの名前を指定します。
    • MaxConcurrentDynamicSnapshots に、実行する動的スナップショット ジョブの最大数を指定します。サブスクライバがスナップショットを要求するタイミングは不定です。そのため、同時に複数のサブスクライバがパーティション スナップショットを要求した場合に、このプロパティを使って、同時に実行できるスナップショット エージェント ジョブの数を制限します。実行中のジョブが最大数に達した場合は、パーティション スナップショットに対するそれ以降の要求は、実行されているいずれかのジョブが完了するまでキューに格納されます。
    • ビットごとの論理和演算 (Visual C# の場合は |、Visual Basic の場合は Or) を使用して、AllowSubscriberInitiatedSnapshot 値を Attributes に追加します。
    • SnapshotGenerationAgentProcessSecurityLogin フィールドおよび Password フィールドに、スナップショット エージェント ジョブの実行に使用する Microsoft Windows アカウントの資格情報を指定します。
      ms147336.note(ja-jp,SQL.90).gifメモ :
         パブリケーションが固定サーバー ロール sysadmin のメンバによって作成された場合、SnapshotGenerationAgentProcessSecurity を設定することをお勧めします。詳細については、「レプリケーション エージェントのセキュリティ モデル」を参照してください。
  5. Create メソッドを呼び出して、パブリケーションを作成します。

    ms147336.security(ja-jp,SQL.90).gifセキュリティ メモ :
    リモート ディストリビュータを使用するパブリッシャを構成する場合は、SnapshotGenerationAgentProcessSecurity を含むすべてのプロパティに指定された値がディストリビュータにプレーン テキストとして送信されます。Create メソッドを呼び出す前に、パブリッシャとそのリモート ディストリビュータ間の接続を暗号化する必要があります。詳細については、「SQL Server への接続の暗号化」を参照してください。
  6. MergeArticle プロパティを使用して、アーティクルをパブリケーションに追加します。パラメータ化されたフィルタを定義する FilterClause プロパティを少なくとも 1 つのアーティクルについて指定します。(省略可) アーティクル間の結合フィルタを定義する MergeJoinFilter オブジェクトを作成します。詳細については、「アーティクルを定義する方法 (RMO プログラミング)」を参照してください。

  7. SnapshotAgentExists の値が false の場合は、CreateSnapshotAgent を呼び出して、このパブリケーション用の初期スナップショット エージェント ジョブを作成します。

  8. 手順 4. で作成した MergePublication オブジェクトの StartSnapshotGenerationAgentJob メソッドを呼び出します。これにより、初期スナップショットを生成するエージェント ジョブが開始されます。初期スナップショットの作成と、スナップショット エージェントのカスタム スケジュールの定義については、「初期スナップショットを作成する方法 (RMO プログラミング)」を参照してください。

  9. (省略可) 初期スナップショットが使用できる状態にあるかを調べるには、SnapshotAvailable プロパティの値が true であることを確認します。

  10. サブスクライバのマージ エージェントの初回接続時に、パーティション スナップショットが自動的に生成されます。

パブリケーションを作成し、スナップショットを事前に生成したり、自動的に更新するには

  1. MergePublication クラスのインスタンスを使用して、マージ パブリケーションを定義します。詳細については、「パブリケーションを作成する方法 (RMO プログラミング)」を参照してください。

  2. MergeArticle プロパティを使用して、アーティクルをパブリケーションに追加します。パラメータ化されたフィルタを定義する FilterClause プロパティを少なくとも 1 つのアーティクルについて指定し、さらに、必要に応じて、アーティクル間の結合フィルタを定義する MergeJoinFilter オブジェクトを作成します。詳細については、「アーティクルを定義する方法 (RMO プログラミング)」を参照してください。

  3. SnapshotAgentExists の値が false の場合は、CreateSnapshotAgent を呼び出して、このパブリケーション用のスナップショット エージェント ジョブを作成します。

  4. 手順 1. で作成した MergePublication オブジェクトの StartSnapshotGenerationAgentJob メソッドを呼び出します。このメソッドにより、初期スナップショットを生成するエージェント ジョブが開始されます。初期スナップショットを生成する方法、およびスナップショット エージェントのカスタム スケジュールを定義する方法については、「初期スナップショットを作成する方法 (RMO プログラミング)」を参照してください。

  5. SnapshotAvailable プロパティの値が true であることを確認し、初期スナップショットが使用できる状態にあるかを調べます。

  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. の Server オブジェクトの JobServer プロパティと、手順 12. のジョブ名を渡します。

  16. Start メソッドを呼び出して、パーティション スナップショットを要求するジョブを開始します。

  17. 手順 6. から手順 16. を各サブスクライバについて繰り返します。

パブリケーションを作成し、各パーティションのスナップショットを手動で作成するには

  1. MergePublication クラスのインスタンスを使用して、マージ パブリケーションを定義します。詳細については、「パブリケーションを作成する方法 (RMO プログラミング)」を参照してください。

  2. MergeArticle プロパティを使用して、パブリケーションにアーティクルを追加します。パラメータ化されたフィルタを定義する FilterClause プロパティを少なくとも 1 つのアーティクルについて指定し、さらに、必要に応じて、アーティクル間の結合フィルタを定義する MergeJoinFilter オブジェクトを作成します。詳細については、「アーティクルを定義する方法 (RMO プログラミング)」を参照してください。

  3. 初期スナップショットを生成します。詳細については、「初期スナップショットを作成する方法 (RMO プログラミング)」を参照してください。

  4. SnapshotGenerationAgent クラスのインスタンスを作成し、次の必須プロパティを設定します。

  5. ReplicationTypeMerge を設定します。

  6. 次に示したプロパティを少なくとも 1 つ設定し、パーティションのパラメータを定義します。

  7. GenerateSnapshot メソッドを呼び出します。

  8. 手順 4. から手順 7. を各サブスクライバについて繰り返します。

使用例

次の例では、サブスクライバがスナップショット生成を要求できるマージ パブリケーションを作成します。

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

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 = "AdventureWorks"

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 = "AdventureWorks";
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 = "AdventureWorks"
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 = "AdventureWorks";
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 = "AdventureWorks"
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

参照

処理手順

パラメータ化されたフィルタを使用してマージ レプリケーションのスナップショットを作成する方法 (レプリケーション Transact-SQL プログラミング)

その他の技術情報

パラメータ化されたフィルタを使用してマージ パブリケーションのスナップショットを生成する方法 (SQL Server Management Studio)
パラメータ化されたフィルタを使用したマージ パブリケーションのスナップショット

ヘルプおよび情報

SQL Server 2005 の参考資料の入手