6

Ich verwende die Microsoft Data-Tier Application framework, um ein Bereitstellungsskript basierend auf einem DacPackage Objekt zu erstellen. Ich versuche, die Microsoft.SqlServer.Management.Smo.Server Klasse zu verwenden, um dieses Skript ...ServerConnection.ExecuteNonQuery im SQLCMD-Modus

SqlConnection deployConnection = new SqlConnection(connBuilder.ToString()); 
deployConnection.Open(); 
Server server = new Server(new ServerConnection(deployConnection)); 
server.ConnectionContext.ExecuteNonQuery(deployScript); 

jedoch auszuführen, diese Fehler aus mit ...

Unhandled Exception: Microsoft.SqlServer.Management.Common.ExecutionFailureException: 
    An exception occurred while executing a Transact-SQL statement or batch. ---> 
    System.Data.SqlClient.SqlException: Incorrect syntax near ':'. 

Ich weiß, dass die Antwort auf dieses Problem ist, dass ich im SQLCMD-Modus zu sein, aber ich weiß nicht, wie ich meinem ServerConnection mitteilen soll, in diesem Modus ausgeführt zu werden.

Ich denke, mein Problem ist nicht so spezifisch wie das, was ich im Titel behaupte. Was ich wirklich tun muss, ist das Ausführen des aus dem DacPackage generierten Skripts über das .Net-Framework. Kann mir jemand dabei helfen?

Antwort

9

SQLCMD-Modusbefehle sind nicht T-SQL-Befehle; Sie funktionieren nur in SQL Server-Verwaltungsstudio (SSMS)/Visual Studio (VS) und SQLCMD.EXE. SQLCMD-Modus ist inhärent wie SQLCMD.EXE funktioniert und kann manuell in SSMS/VS aktiviert werden; Es ist ein Teil dieser Anwendungen und nicht etwas, was über einen Provider gemacht werden kann.

Diese Anwendungen interpretieren die SQLCMD-Modusbefehle und leiten sie nicht an SQL Server weiter. SQLCMD-Modus-Befehle werden zuerst geparst/ausgeführt (auf diese Weise können sie das SQL beeinflussen, das gerade gesendet wird) und dann wird die endgültige Version des SQL an SQL Server übergeben.

Daher müssen die Deployment-SQL-Skripts, die von SQL Server-Datentools (SSDT) ​​/ Visual Studio generiert werden, über eines dieser drei Programme ausgeführt werden.

Da Sie eine .dacpac Datei bereits haben, bietet Microsoft ein paar Möglichkeiten, diejenigen zu veröffentlichen, sollten Sie prüfen:

Sie können auch erstellen SQL-Skript über DacServices.GenerateDeployScript() veröffentlichen, aber das wird die Situation nicht ändern, wie oben angegeben, da die Publish/bereitstellen SQL-Skript, ob von Visual Studio generiert „Publish {project_name}“ oder GenerateDeployScript(), ist das gleiche Skript. Das heißt, es wird die SQLCMD-Modus Doppelpunkt-Befehle wie :setvar und :on error exit sowie der SQLCMD-Modus Variablen hat, die zumindest $(DatabaseName) sein wird, die in der folgenden Zeile verwendet wird:

USE [$(DatabaseName)]; 

Während Es ist möglich, die ursprünglichen :setvar Zeilen durch Setzen der DacDeployOptions Eigenschaft von CommentOutSetVarDeclarations zu true, die immer noch die :on error exit Linie sowie eine Zeile für :setvar __IsSqlCmdEnabled "True", die verwendet wird, um festzustellen, ob SQLCMD-Modus aktiviert wurde oder nicht aktiviert ist. Genau über diese besondere :setvar Zeile ist ein Kommentar besagt:

/* 
Detect SQLCMD mode and disable script execution if SQLCMD mode is not supported. 
To re-enable the script after enabling SQLCMD mode, execute the following: 
SET NOEXEC OFF; 
*/ 

Also wirklich sie nicht die Absicht, dass dieses Skript nur über SQLCMD ausgeführt wird, sei es durch DOS -> sqlcmd.exe oder Powershell -> Invoke-Sqlcmd.

Technisch ist es möglich, eine Zeichenfolge des Deploy-Skriptinhalts (statt einer stream) zu generieren und diese Zeichenfolge zu bearbeiten, indem a) alle Doppelpunktbefehle entfernt und b) "$ (DatabaseName)" durch irgendwas ersetzt wird Datenbank, die Sie bereitstellen möchten. Ich habe dies jedoch nicht versucht, ich empfehle das nicht, und ich bin mir nicht sicher, ob es in allen Situationen funktionieren würde, welche Bereitstellungsskripts von SQL Server-Datentools generiert werden könnten. Aber es scheint wie eine Option.

Auch in geringem Zusammenhang: Sie benötigen keine SMO zum Ausführen von SQL-Skripts. SMO ist ein Mittel zur Interaktion mit SQL Server über Objekte und nicht direkt über T-SQL-Befehle.

EDIT:
Links, wo andere versucht haben, diese und fand es nicht funktioniert hat:

Möglichkeiten für das Erhalten der veröffentlichen generierte SQL-Skript zu arbeiten programmatisch:

+0

So gibt es * keine * Art und Weise die erzeugten sQLCMD-Skripts aus dem .NET-Framework programmatisch auszuführen - ist das, was Sie sagen? –

+3

@DanForbes - ziemlich, ja. Nichts außerhalb dieser 3 Programme hat irgendeinen Hinweis darauf, was diese Doppelpunktbefehle sind. ABER, das bedeutet nicht, dass Sie einen Prozess in C# nicht starten können, um die Befehlszeile für "SQLCMD.EXE -S Server" aufzurufen und den Skriptnamen und das entsprechende Flag für die Übergabe eines SQL-Skripts anzugeben. –

+1

Vielen Dank, @srutzky! –