Mode SQLCMD dans SSMS et extension @ @ variable

8

Lors de l'utilisation du mode SQLCMD avec SSMS (pas à partir de la ligne de commande), existe-t-il un moyen d'affecter le serveur et l'instance actuels à une variable? Ceci est différent et distinct de l'attribution de variables TSQL ordinaires.

Définition du problème

Je veux utiliser la puissance de l'expansion variable de SQLCMD pour remplacer des valeurs spécifiques à l'environnement dans nos scripts de déploiement au lieu du mash de construction de chaînes tsql existant dans lequel je suis entré. À l'exception de l'environnement actuel, l'utilisation de SQLCMD pour gérer les déploiements s'est extrêmement bien passée.

--
-- 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

Et cela génère les résultats suivants.

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

Le pain de viande dit que 2 sur 3 n'est pas mauvais , mais je préfère avoir une solution à 3 sur 3. Lorsque ce script est déployé sur le serveur de test, je ne veux pas faire confiance aux gens du déploiement pour éditer le script.

Si la seule solution à l'utilisation de SQLCMD consiste à invoquer complètement des scripts à partir de la ligne de commande, je peux accepter cela, mais je voulais jeter cela ici car je suis vert à utiliser SQLCMD.

Sortie désirée

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

Résultats

worked
DEVA\DEV2

Poursuites infructueuses

Le premier lien BOL s'est révélé prometteur, tout ce que j'avais à faire était d'utiliser le SQLCMDSERVER mais en vain. Exécuter dans le contexte de SSMS en mode SQLCMD, il générera une erreur de script fatale

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

Mise à jour Tumbleweed

2011-08-12 Dans une tentative de réduire mon problème à la forme la plus simple, basée sur les réponses, j'ai simplifié à outrance mes requêtes (mes excuses). Une partie de la requête que j'ai utilisée est ci-dessous. Les deux reponders sont corrects dans leurs réponses qui identifient le wrapping @@ nom_serveur dans les graduations, ce qui donne la valeur littérale et pour obtenir la valeur développée, je devrais la déballer des guillemets. Mon désir était d'utiliser la substitution de variables sqlcmd plutôt que la construction de chaînes que le déballage impliquerait.

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

L'invocation de la ligne de commande fonctionne (comme prévu)

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

J'ai essayé et rejeté d'autres permutations de: setvar x @@ servername pour essayer d'obtenir la valeur évaluée de la variable de base de données stockée dans la variable SQLCMD. À ce stade, je suis à peu près certain que les variables sqlcmd sont substituées dans les requêtes avant la compilation des requêtes, mais j'aimerais que leur erreur soit prouvée.

Références BOL

billinkc
la source

Réponses:

3

Les variables SQL-CMD sont évaluées avant l'exécution du lot. Vous ne pouvez donc pas affecter une valeur de variable t-sql à une variable CMD.

Stefan Wilms
la source
Il en est certainement ainsi. Êtes-vous au courant d'une quelconque documentation indiquant qu'il en est ainsi?
billinkc
3

À moins que je manque quelque chose, cela ne fonctionne-t-il pas, sans les apostrophes?:

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

Il renvoie SERVER \ INSTANCE pour moi en mode SQLCMD via SSMS.

Edit 02/12/2018 Après avoir rencontré ma réponse à une autre question, et après avoir examiné, je peux voir le problème, je crois que cela se résume à ceci:

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

Cela génère @@ nomserveur et la sortie souhaitée est la valeur de @@ nomserveur. La seule façon que j'ai vue de le faire est dans la réponse acceptée ici

SqlACID
la source
1
Vous remplacez simplement la chaîne @@servernamepour $(dbNotServer)que le SQL envoyé pour s'exécuter soit SELECT @@servername AS worked. Il n'y a pas d'affectation de la valeur de @@servername à la variable sqlcmd comme demandé.
Martin Smith
1

Sous "Sortie souhaitée", le T-SQL allant vers le serveur devient:

SELECT '@@servername' AS worked

Mettre des guillemets simples en @@servernamefait un littéral de chaîne et ne sera pas remplacé par le nom réel, c'est pourquoi vous voyez @@servernamela valeur.

Si vous cherchez à afficher le nom du serveur, supprimez les guillemets simples, ce qui rend votre T-SQL:

SELECT @@servername AS worked

Je ne suis pas tout à fait clair, je comprends la question, mais voici comment vous obtiendrez ce qui est dans votre "sortie souhaitée".

Pavel
la source