Ich versuche, vom Abonnenten ein Push-Abonnement für eine SQL Server-Publikation einzurichten.
Ich könnte das Abonnement beim Herausgeber mithilfe des Replikationsassistenten in Management Studio einrichten. Ich würde es jedoch vorziehen, den Prozess relativ zum Abonnenten zu skripten, damit ich die Bereitstellung einer neuen SQL Server-Abonnenteninstanz automatisieren kann.
Zunächst frage ich Sie gerne vor der Bereitstellung nach dem Namen des Herausgebers. Wenn dies funktioniert, werde ich nach einer Möglichkeit suchen, den richtigen Wert für meine Umgebung automatisch einzufügen.
Was ist eine einfache Möglichkeit, dies für eine SQL Server-Instanz zu tun, die mehrere Abonnements bei verschiedenen Herausgebern erstellen muss?
Ich bin offen für die Verwendung aller unterstützten SQL Server- Skriptlösungen: SMO, RMO, SQLcmd, WMI, PSDrive und sogar reines T-SQL.
Ich habe versucht, dieses Problem auf zwei Arten zu lösen. Die erste ist eine vollständige Lösung mit T-SQL, die jedoch einige manuelle Schritte umfasst.
Verwenden von T-SQL
Ich habe eine manuelle Lösung in T-SQL. Die Lösung basiert auf der Ausgabe der Management Studio Replication Script Generator-Ausgabe.
Mit Management Studio führe ich das folgende Skript aus, um ein T-SQL-Skript zu generieren, das ich beim Herausgeber ausführen kann:
PRINT N'
EXECUTE MyDatabase.dbo.sp_addsubscription
@publication = N''MyPublication'',
@subscriber = ''' + CAST(SERVERPROPERTY('ServerName') AS SYSNAME) + ''',
@destination_db = ''SubscriberDatabase'',
@subscription_type = N''Push'',
@sync_type = N''automatic'',
@article = N''all'',
@update_mode = N''read only'',
@subscriber_type = 0;
EXECUTE MyDatabase.dbo.sp_addpushsubscription_agent
@publication = N''MyPublication'',
@subscriber = ''' + CAST(SERVERPROPERTY('ServerName') AS SYSNAME) + ''',
@subscriber_db = ''SubscriberDatabase'',
@job_login = null,
@job_password = null,
@subscriber_security_mode = 1,
@frequency_type = 64,
@frequency_interval = 1,
@frequency_relative_interval = 1,
@frequency_recurrence_factor = 0,
@frequency_subday = 4,
@frequency_subday_interval = 5,
@active_start_time_of_day = 0,
@active_end_time_of_day = 235959,
@active_start_date = 0,
@active_end_date = 0,
@dts_package_location = N''Distributor'';';
In der MYSUBSCRIBER-Instanz würde die Ausgabe folgendermaßen aussehen:
EXECUTE MyDatabase.dbo.sp_addsubscription
@publication = N'MyPublication',
@subscriber = 'MYSUBSCRIBER',
@destination_db = 'SubscriberDatabase',
@subscription_type = N'Push',
@sync_type = N'automatic',
@article = N'all',
@update_mode = N'read only',
@subscriber_type = 0;
EXECUTE MyDatabase.dbo.sp_addpushsubscription_agent
@publication = N'MyPublication',
@subscriber = 'MYSUBSCRIBER',
@subscriber_db = 'SubscriberDatabase',
@job_login = null,
@job_password = null,
@subscriber_security_mode = 1,
@frequency_type = 64,
@frequency_interval = 1,
@frequency_relative_interval = 1,
@frequency_recurrence_factor = 0,
@frequency_subday = 4,
@frequency_subday_interval = 5,
@active_start_time_of_day = 0,
@active_end_time_of_day = 235959,
@active_start_date = 0,
@active_end_date = 0,
@dts_package_location = N'Distributor';
Ich kopiere die Ausgabe und führe das Skript in der Herausgeberinstanz aus, um das Abonnement einzurichten.
Ich glaube, ich kann dies in reinem T-SQL nicht automatisieren, ohne das Skript vor dem Ausführen zu bearbeiten, da T-SQL von Entwurf keine Benutzereingaben verarbeitet.
Verwenden von PowerShell und RMO
PowerShell bietet einfache Möglichkeiten zur Verarbeitung von Benutzereingaben. Dies scheint also eine gute Möglichkeit zu sein, den Automatisierungsprozess zu prototypisieren.
MSDN verfügt über eine Anleitung in acht Schritten zum Einrichten eines Push-Abonnements mithilfe der .NET Replication Management Objects (RMO).
Hier sind die ersten beiden Schritte:
- Erstellen Sie mithilfe der ServerConnection- Klasse eine Verbindung zum Publisher .
- Erstellen Sie eine Instanz der TransPublication- Klasse mithilfe der Publisher-Verbindung aus Schritt 1. Geben Sie Name , DatabaseName und ConnectionContext an .
Ich versuche, diese Schritte in ein PowerShell-Skript zu übersetzen, komme aber nicht über Schritt 2 hinaus.
In den folgenden Codebeispielen verwende ich fiktive Objektnamen. Ich glaube, dies hat keinen Einfluss auf die Beantwortbarkeit der Frage, da die Fehlermeldung identisch ist, wenn ich die tatsächlichen Objektnamen verwende.
Erster Versuch: Festlegen der Eigenschaften
Mein erster Versuch besteht darin, das TransReplication-Objekt zu erstellen und dann seine Eigenschaften festzulegen. Der Code sieht folgendermaßen aus:
Add-Type -AssemblyName "Microsoft.SqlServer.Rmo, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91";
$Publisher = New-Object Microsoft.SqlServer.Management.Common.ServerConnection MyServer
$Publication = New-Object Microsoft.SqlServer.Replication.TransPublication
$Publication.Name = 'MyPublication'
$Publication.DatabaseName = 'MyDatabase'
$Publication.ConnectionContext = $Publisher
Wenn ich dieses Skript ausführe, wird der folgende Fehler angezeigt:
Exception setting "ConnectionContext": "Cannot convert the "server='(local)';Trusted_Connection=true;multipleactiveresultsets=false" value
of type "Microsoft.SqlServer.Management.Common.ServerConnection" to type "Microsoft.SqlServer.Management.Common.ServerConnection"."
At line:8 char:14
+ $Publication. <<<< ConnectionContext = $Publisher
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
Es sieht so aus, als ob es fehlschlägt, weil es den Typ nicht ServerConnection
in den Typ konvertieren kann ServerConnection
. Ich verstehe nicht, wie dies aus dem angegebenen Grund fehlschlagen könnte, da der Wert bereits vom erforderlichen Typ ist.
Zweiter Versuch: Überladen des Konstruktors
Mein zweiter Versuch besteht darin, die Eigenschaftswerte des TransReplication-Objekts im Konstruktor anzugeben. Der Code sieht folgendermaßen aus:
Add-Type -AssemblyName "Microsoft.SqlServer.Rmo, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91";
$Publisher = New-Object Microsoft.SqlServer.Management.Common.ServerConnection MyServer
$Publication = New-Object Microsoft.SqlServer.Replication.TransPublication 'MyPublication', 'MyDatabase', $Publisher
Wenn ich dieses Skript ausführe, wird der folgende Fehler angezeigt:
New-Object : Cannot find an overload for "TransPublication" and the argument count: "3".
At line:5 char:26
+ $Publication = New-Object <<<< -TypeName Microsoft.SqlServer.Replication.TransPublication 'MyPublication', 'MyDatabase', $Publisher
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
Es sieht so aus, als ob das Cmdlet New-Object den von MSDN dokumentierten Konstruktor mit drei Argumenten nicht finden kann :
public TransPublication( string name, string databaseName, ServerConnection connectionContext )
Parameter
- Name
Typ: System.String
Ein String Wert, der den Namen der Veröffentlichung angibt.- Datenbankname
Typ: System.String
Ein String - Wert, der den Namen der Publikationsdatenbank angibt.- connectionContext
Typ: Microsoft.SqlServer.Management.Common.ServerConnection
Ein ServerConnection- Objekt, das eine Verbindung zum Publisher oder zum Distributor für einen Nicht-SQL Server-Publisher darstellt.
Soweit ich das beurteilen kann, überlade ich den Konstruktor korrekt.
Mache ich etwas falsch? Hat meine Umgebung etwas Ungewöhnliches? Bin ich besser dran, eine andere Lösung zu verwenden?