Variable innerhalb einer anderen Variablen im SQLCMD-Modus


9

Beim Versuch, mein SQL-Skript im SQLCMD-Modus aufzuräumen, stieß ich auf ein Problem:

:setvar db_suffix "some_suffix"
:setvar some_db "some_db_$(db_suffix)"
print 'some_db: $(some_db)'

Die Ausgabe davon ist:

some_db: some_db_$(db_suffix)

Was ich jedoch erwartet hatte, war:

some_db: some_db_some_suffix

Gibt es eine Möglichkeit, eine solche variable Interpolation durchzuführen?

(Beachten Sie, dass T-SQL-Funktionen wie CONCAT()nicht funktionieren, da ich die Variable als Datenbanknamen verwenden werde.)


2
Der SQLCMD-Modus führt nur einen Durchgang aus, daher glaube ich nicht, dass Sie solche Variablen-Feed-Variablen haben können. Sie müssen etwas extern tun (PowerShell?) Oder eine Datei als Vermittler verwenden. Siehe diesen Blog-Beitrag .
Aaron Bertrand

Antworten:


13

Gibt es eine Möglichkeit, eine solche variable Interpolation durchzuführen?

In gewisser Weise irgendwie. Nur nicht direkt.

Sie müssen einige Dinge beachten:

  1. Der Wert, auf den Sie eine Variable setzen, :setvarist ein einfacher Literalwert. Sie können dies sehen, indem Sie nur die folgenden zwei Zeilen ausführen:

    :setvar var1 $(var2)
    PRINT '$(var1)';

    was zurückgibt:

    $(var2)

    Wenn der SQLCMD / SQLCMD-Modus versuchen würde, den Wertteil von :setvarin irgendeiner Weise zu analysieren , würde dies zu einem Fehler führen, wenn er $(var2)nicht definiert wird.

  2. Das Ersetzen von Variablen ist in einigen anderen SQLCMD-Befehlen zulässig.

    Dies bedeutet, dass Sie beispielsweise einen Shell-Befehl ausführen können, während Sie eine SQLCMD-Variable an diese Befehlszeile übergeben:

    :setvar db_suffix some_suffix
    !! echo :setvar other_db [MyDB_$(db_suffix)] > c:\TEMP\setvar.txt

    Die beiden obigen Zeilen erstellen / überschreiben eine Datei C: \ TEMP \ setvar.txt mit dem Text ": setvar other_db [MyDB _ $ (db_suffix)]", wobei sie $(db_suffix)durch den Wert "some_suffix" ersetzt wird.

  3. SQLCMD-Befehle in einer Datei / einem Skript, die bzw. das über den :rBefehl importiert wird, werden in einem zweiten Durchgang verarbeitet, sodass die in diesen externen Dateien festgelegten Variablen im Hauptskript wiedergegeben werden können:

    :setvar db_suffix some_suffix
    !! echo :setvar other_db [MyDB_$(db_suffix)] > c:\TEMP\setvar.txt
    :r C:\TEMP\setvar.txt
    PRINT 'somethin_somethin: $(other_db)';

    Kehrt zurück:

    somethin_somethin: [MyDB_some_suffix]
  4. SQLCMD-Befehle werden pro Stapel interpretiert !! Wenn Sie also den verketteten Wert ändern möchten, müssen Sie jedes Erstellen und Lesen der temporären Datei trennen. Andernfalls wird der Wert, den Sie erhalten, als letzter festgelegt, da alle Befehle !!und :rvor den Variablenwerten verarbeitet werden werden ersetzt, und dann kann der Stapel an SQL Server gesendet werden, um das T-SQL zu verarbeiten. Zum Beispiel:

    :setvar db_suffix some_suffixes
    
    !! echo :setvar other_db [MyDB_$(db_suffix)] > c:\TEMP\setvar.txt
    :r C:\TEMP\setvar.txt
    PRINT 'somethin_somethin: $(other_db)';
    
    --GO
    
    !! echo :setvar other_db [NotMyDB_$(db_suffix)22] > c:\TEMP\setvar.txt
    :r C:\TEMP\setvar.txt
    PRINT 'somethin_somethin2: $(other_db)'

    Wird zurückkehren:

    somethin_somethin: [NotMyDB_some_suffixes22]
    somethin_somethin2: [NotMyDB_some_suffixes22]

    ABER, kommentieren Sie das aus --GOund Sie erhalten Folgendes:

    somethin_somethin: [MyDB_some_suffixes]
    somethin_somethin2: [NotMyDB_some_suffixes22]

0

ein bisschen knifflig

:setvar var2 'aaa'
:setvar var1 "'$var2'"
PRINT '$var2  =' + $(var2);
PRINT '$var1  =' + $(var1);
PRINT '$var1  =' + REPlACE( $(var1) , '$var2' , $(var2) );

AUSGABE

$var2  =aaa
$var1  =$var2
$var1  =aaa

Es ist nicht klar, wie dies die Frage beantwortet. Bitte bearbeiten Sie es so, dass es die Ausgabe erzeugt, die der Fragesteller erwartet.
Colin 't Hart
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.