SQLCMD-Modus in SSMS und @@ Variablenerweiterung


8

Gibt es bei Verwendung des SQLCMD-Modus mit SSMS (nicht über die Befehlszeile) eine Möglichkeit, den aktuellen Server und die aktuelle Instanz einer Variablen zuzuweisen? Dies unterscheidet sich von der Zuweisung gewöhnlicher TSQL-Variablen.

Problem Definition

Ich möchte die Leistungsfähigkeit der variablen Erweiterung von SQLCMD nutzen, um umgebungsspezifische Werte in unseren Bereitstellungsskripten anstelle des vorhandenen Mashs zum Erstellen von tsql-Zeichenfolgen zu ersetzen, auf den ich eingegangen bin. Mit einer Ausnahme der aktuellen Umgebung ist die Verwendung von SQLCMD zur Verarbeitung von Bereitstellungen sehr gut verlaufen.

--
-- define 2 sqlcmd variables that will be expanded in scripts
--
:setvar dbServer "DEVA2\DEV2"
:setvar dbNotServer @@servername

SELECT
    '$(dbServer)' AS hard_coded_value
,   @@servername AS [servername]
,   '$(dbNotServer)' AS dbNotServer

Und das führt zu folgenden Ergebnissen.

hard_coded_value  servername  dbNotServer
DEVA2\DEV2        DEVA2\DEV2  @@servername

Meat Loaf sagt, 2 von 3 sind nicht schlecht , aber ich hätte lieber eine 3 von 3 Lösung. Wenn dieses Skript auf dem Testserver bereitgestellt wird, möchte ich den Bereitstellungsmitarbeitern beim Bearbeiten des Skripts nicht vertrauen.

Wenn die einzige Lösung für die Verwendung von SQLCMD darin besteht, Skripte vollständig über die Befehlszeile aufzurufen, kann ich das akzeptieren, wollte dies aber hier rauswerfen, da ich mit der Verwendung von SQLCMD grün bin.

Gewünschte Ausgabe

:setvar dbNotServer @@servername
SELECT '$(dbNotServer)' AS worked

Ergebnisse

worked
DEVA\DEV2

Fruchtlose Beschäftigungen

Der erste BOL-Link war vielversprechend. Ich musste lediglich den SQLCMDSERVER verwenden, aber ohne Erfolg. Wird es im Kontext von SSMS im SQLCMD-Modus ausgeführt, wird ein schwerwiegender Skriptfehler ausgegeben

-- A fatal scripting error occurred.
-- Variable SQLCMDSERVER is not defined.
SELECT '$(SQLCMDSERVER)' AS [FatalScriptingError]

Tumbleweed Update

2011-08-12 Um mein Problem auf der Grundlage der Antworten auf die einfachste Form zu reduzieren, habe ich meine Fragen zu stark vereinfacht (ich entschuldige mich). Ein Teil der von mir verwendeten Abfrage ist unten. Die beiden Reponder sind in ihren Antworten korrekt. Wenn Sie angeben, dass das Umschließen von @@ Servername in Häkchen den Literalwert ergibt, muss der erweiterte Wert aus den Anführungszeichen entfernt werden, um den erweiterten Wert zu erhalten. Mein Wunsch war es, die sqlcmd-Variablensubstitution anstelle der String-Erstellung zu verwenden, die das Entpacken mit sich bringen würde.

INSERT INTO
    dbo.SSISCONFIG
(
    ConfigurationFilter
,   ConfiguredValue
,   PackagePath
,   ConfiguredValueType
,   Application
,   Category
,   Subcategory
,   Comment
)
SELECT
    'Default.Accounting' AS ConfigurationFilter
,   'Data Source=$(dbServer);Initial Catalog=Accounting;Provider=SQLNCLI10.1;Integrated Security=SSPI;Packet Size=32767;' AS ConfiguredValue
,   '\Package.Connections[Accounting].Properties[ConnectionString]' AS PackagePath
,   'String' AS ConfiguredValueType
,   'Defaults' AS Application
,   'Connection' AS Category
,   'Database' AS Subcategory
,   'Default connection string' AS Comment
SELECT
    'Default.$(sqlVersion).CorporateReporting' AS ConfigurationFilter
,   'Data Source=$(dwServer);Initial Catalog=CRDS;Provider=SQLNCLI10.1;Integrated Security=SSPI;Packet Size=32767;' AS ConfiguredValue
,   '\Package.Connections[CorporateReporting].Properties[ConnectionString]' AS PackagePath
,   'String' AS ConfiguredValueType
,   'Defaults' AS Application
,   'Connection' AS Category
,   'Database' AS Subcategory
,   'Default connection string' AS Comment

Befehlszeilenaufruf funktioniert (wie erwartet)

C:\>sqlcmd -E -d master -S DEVA2\DEV2 -Q "SELECT '$(SQLCMDSERVER)' AS [servername]"

Ich habe versucht, andere Permutationen von: setvar x @@ servername zu verwerfen, um den ausgewerteten Wert der Datenbankvariablen zu erhalten, die in der SQLCMD-Variablen gespeichert ist. An diesem Punkt bin ich mir ziemlich sicher, dass die sqlcmd-Variablen vor der Abfragekompilierung in Abfragen ersetzt werden, würde sich aber gerne als falsch erweisen.

BOL Referenzen

Antworten:


3

SQL-CMD-Variablen werden ausgewertet, bevor der Stapel ausgeführt wird. Sie können einer CMD-Variablen also keinen t-sql-Variablenwert zuweisen.


Es scheint sicherlich so. Kennen Sie Unterlagen, aus denen hervorgeht, dass dies der Fall ist?
Billinkc

3

Funktioniert das nicht ohne die Apostrophe, es sei denn, ich vermisse etwas?:

:setvar dbNotServer @@servername
SELECT $(dbNotServer) AS worked

Es gibt SERVER \ INSTANCE für mich im SQLCMD-Modus über SSMS zurück.

Bearbeiten 02/12/2018 Nachdem ich auf meine Antwort auf eine andere Frage gestoßen und sie überprüft habe, kann ich das Problem sehen. Ich glaube, es läuft darauf hinaus:

:setvar dbNotServer @@servername
print '$(dbNotServer)'

Dies gibt @@ Servername aus und die gewünschte Ausgabe ist der Wert von @@ Servername. Der einzige Weg, den ich gesehen habe, um dies zu tun, ist in der akzeptierten Antwort hier


1
Sie ersetzen nur die Zeichenfolge @@servernamefür $(dbNotServer)so die SQL auszuführen gesendet SELECT @@servername AS worked. Es gibt keine Zuordnung des Werts von @@servername zur gewünschten sqlcmd-Variablen.
Martin Smith

1

Unter "Gewünschte Ausgabe" wird das zum Server gehende T-SQL zu:

SELECT '@@servername' AS worked

Wenn Sie einfache Anführungszeichen setzen, @@servernamewird dies zu einem Zeichenfolgenliteral und nicht durch den tatsächlichen Namen ersetzt. Aus diesem Grund wird @@servernameder Wert als Wert angezeigt.

Wenn Sie den Servernamen anzeigen möchten, entfernen Sie die einfachen Anführungszeichen, um T-SQL zu erstellen:

SELECT @@servername AS worked

Ich bin mir nicht ganz sicher, ob ich die Frage verstehe, aber so erhalten Sie, was in Ihrer "gewünschten Ausgabe" enthalten ist.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.