web-dev-qa-db-fra.com

Variable à l'intérieur d'une autre variable en mode SQLCMD

En essayant de ranger mon script SQL avec le mode SQLCMD et j'ai rencontré un problème:

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

La sortie de cela est:

some_db: some_db_$(db_suffix)

Cependant, ce que j'attendais était:

some_db: some_db_some_suffix

Existe-t-il un moyen d'avoir une interpolation variable comme celle-ci?

(Notez que les fonctions T-SQL telles que CONCAT() ne fonctionneront pas car je vais utiliser la variable comme nom de base de données).

9
user193130

Existe-t-il un moyen d'avoir une interpolation variable comme celle-ci?

En quelque sorte, en quelque sorte. Mais pas directement.

Vous devez garder à l'esprit quelques éléments:

  1. La valeur à laquelle vous définissez une variable via :setvar Est une valeur littérale simple. Vous pouvez le voir en exécutant uniquement les deux lignes suivantes:

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

    qui renvoie:

    $(var2)
    

    Si le mode SQLCMD/SQLCMD tentait d'analyser la partie valeur de :setvar De quelque façon que ce soit, cela entraînerait une erreur si $(var2) n'était pas définie.

  2. La substitution de variable est autorisée dans certaines autres commandes SQLCMD.

    Cela signifie que vous pouvez, par exemple, exécuter une commande Shell tout en transmettant une variable SQLCMD à cette ligne de commande:

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

    Les deux lignes ci-dessus vont créer/écraser un fichier, C:\TEMP\setvar.txt, avec le texte de ": setvar other_db [MyDB _ $ (db_suffix)]" "où $(db_suffix) est remplacé par sa valeur "some_suffix".

  3. Les commandes SQLCMD dans un fichier/script importé via la commande :r Sont traitées dans un deuxième passage, permettant aux variables définies dans ces fichiers externes d'être reflétées dans le script principal:

    :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)';
    

    Retour:

    somethin_somethin: [MyDB_some_suffix]
    
  4. Les commandes SQLCMD sont interprétées pour chaque lot !! Donc, si vous souhaitez modifier la valeur concaténée, vous devez séparer chaque création et lecture du fichier temporaire, sinon la valeur que vous obtiendrez sera la dernière à être définie car tous les !! Et :r Les commandes seront traitées avant que les valeurs des variables ne soient remplacées, et puis le lot peut être soumis à SQL Server pour traiter le T-SQL . Par exemple:

    :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)'
    

    Reviendra:

    somethin_somethin: [NotMyDB_some_suffixes22]
    somethin_somethin2: [NotMyDB_some_suffixes22]
    

    MAIS, décommentez le --GO Et vous obtiendrez ce qui suit:

    somethin_somethin: [MyDB_some_suffixes]
    somethin_somethin2: [NotMyDB_some_suffixes22]
    
13
Solomon Rutzky

un peu délicat

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

PRODUCTION

$var2  =aaa
$var1  =$var2
$var1  =aaa
0
john