Modo SQLCMD en SSMS y expansión @@ variable

8

Cuando se utiliza el modo SQLCMD con SSMS (no desde la línea de comandos), ¿hay alguna forma de asignar el servidor y la instancia actuales a una variable? Esto es diferente y distinto de asignar variables TSQL ordinarias.

Definición del problema

Quiero usar el poder de la expansión variable de SQLCMD para sustituir los valores específicos del entorno en nuestros scripts de implementación en lugar de la mezcla de construcción de cadenas tsql existente en la que he entrado. Con la única excepción del entorno actual, el uso de SQLCMD para manejar implementaciones ha ido extremadamente bien.

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

Y eso genera los siguientes resultados.

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

Meat Loaf dice que 2 de 3 no está mal , pero prefiero tener una solución 3 de 3. Cuando esa secuencia de comandos se implementa en el servidor de prueba, no quiero confiar en la gente de implementación con la edición de la secuencia de comandos.

Si la única solución para usar SQLCMD es invocar scripts por completo desde la línea de comandos, puedo aceptar eso, pero quería tirar esto aquí, ya que soy verde para usar SQLCMD.

Salida deseada

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

Resultados

worked
DEVA\DEV2

Búsquedas infructuosas

El primer enlace BOL se mostró prometedor, todo lo que tuve que hacer fue usar el SQLCMDSERVER pero fue en vano. Ejecutar dentro del contexto de SSMS en modo SQLCMD, arrojará un error de secuencia de comandos fatal

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

Actualización de Tumbleweed

2011-08-12 En un intento por reducir mi problema a la forma más simple, basado en las respuestas, simplifiqué mis consultas (mis disculpas). Una parte de la consulta que utilicé está debajo. Los dos respondedores son correctos en sus respuestas que identifican el ajuste de @@ servername en marcas de verificación en el valor literal y para obtener el valor expandido, necesitaría desenvolverlo de las comillas. Mi deseo era usar la sustitución de variables sqlcmd en lugar de la construcción de cadenas que implicaría desenvolver.

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

La invocación de línea de comando funciona (como se esperaba)

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

Intenté y descarté otras permutaciones de: setvar x @@ servername en un intento de obtener el valor evaluado de la variable de la base de datos almacenada en la variable SQLCMD. En este punto, estoy bastante seguro de que las variables sqlcmd están sustituidas en consultas antes de la compilación de la consulta, pero me encantaría que se demuestre que están equivocadas.

Referencias BOL

billinkc
fuente

Respuestas:

3

Las variables SQL-CMD se evalúan antes de que se ejecute el lote. Por lo tanto, no puede asignar un valor de variable t-sql a una variable CMD.

Stefan Wilms
fuente
Ciertamente parece de esa manera. ¿Conoces alguna documentación que indique que esto es así?
billinkc
3

A menos que me falte algo, ¿no funciona esto, sin los apóstrofes ?:

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

Devuelve SERVER \ INSTANCE para mí en modo SQLCMD a través de SSMS.

Editar 02/12/2018 Después de encontrar mi respuesta a otra pregunta y revisar, puedo ver el problema, creo que se reduce a esto:

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

Esto genera @@ servername , y la salida deseada es el valor de @@ servername. La única forma en que he visto hacer esto es en la respuesta aceptada aquí

SqlACID
fuente
1
Simplemente sustituya la cadena @@servernamepor $(dbNotServer)lo que el SQL enviado para ejecutar es SELECT @@servername AS worked. No hay asignación del valor de @@servername a la variable sqlcmd como se solicitó.
Martin Smith
1

En "Salida deseada", el T-SQL que va al servidor se convierte en:

SELECT '@@servername' AS worked

Poner comillas simples alrededor lo @@servernameconvierte en un literal de cadena y no se reemplazará con el nombre real, por lo que está viendo @@servernamecomo el valor.

Si está buscando mostrar el nombre del servidor, elimine las comillas simples, haciendo que su T-SQL:

SELECT @@servername AS worked

No estoy del todo claro, entiendo la pregunta, pero así es como obtendría lo que está en su "Salida deseada".

Pavel
fuente