Modo SQLCMD no SSMS e @@ de expansão variável

8

Ao usar o modo SQLCMD no SSMS (não na linha de comando), existe uma maneira de atribuir o servidor e a instância atuais a uma variável? Isso é diferente e distinto da atribuição de variáveis ​​TSQL comuns.

Definição de problema

Desejo usar o poder da expansão variável do SQLCMD para substituir valores específicos do ambiente em nossos scripts de implantação, em vez do mash de construção de cadeia de caracteres tsql existente em que eu entrei. Com a única exceção do ambiente atual, o uso do SQLCMD para lidar com implantações foi extremamente bem.

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

E isso gera os seguintes resultados.

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

O Meat Loaf diz que 2 em 3 não são ruins , mas eu prefiro ter uma solução em 3 em 3. Quando esse script é implantado no servidor de teste, não quero confiar na equipe de implantação na edição do script.

Se a única solução para usar o SQLCMD é invocar scripts completamente a partir da linha de comando, posso aceitar isso, mas desejei jogar isso aqui, pois estou verde em usar o SQLCMD.

Saída desejada

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

Resultados

worked
DEVA\DEV2

Atividades infrutíferas

O primeiro link BOL mostrou-se promissor, tudo o que eu precisava fazer era usar o SQLCMDSERVER, mas sem sucesso. Executar dentro do contexto do SSMS no modo SQLCMD, gerará um erro fatal de script

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

Atualização Tumbleweed

2011-08-12 Na tentativa de reduzir meu problema da forma mais simples, com base nas respostas, simplifiquei demais minhas consultas (minhas desculpas). Uma parte da consulta que usei está abaixo. Os dois respondedores estão corretos em suas respostas, que identificam a quebra @@ servername em marcas de escala, resulta no valor literal e, para obter o valor expandido, seria necessário desembrulhá-lo das aspas. Meu desejo era usar a substituição de variáveis ​​sqlcmd em vez da construção de strings, que seria desembrulhada.

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

A chamada de linha de comando funciona (conforme o esperado)

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

Tentei e descartei outras permutações de: setvar x @@ servername na tentativa de obter o valor avaliado da variável de banco de dados armazenada na variável SQLCMD. Neste ponto, estou bastante certo de que as variáveis ​​sqlcmd são substituídas em consultas anteriores à compilação de consultas, mas gostariam de ser provadas erradas.

Referências BOL

billinkc
fonte

Respostas:

3

As variáveis ​​SQL-CMD são avaliadas antes da execução do lote. Portanto, você não pode atribuir um valor de variável t-sql a uma variável CMD.

Stefan Wilms
fonte
Certamente parece que sim. Você conhece alguma documentação afirmando que é assim?
billinkc
3

A menos que esteja faltando alguma coisa, isso não funciona, sem os apóstrofos?

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

Ele retorna SERVER \ INSTANCE para mim no modo SQLCMD através do SSMS.

Editar 12/12/2018 Depois de encontrar minha resposta para outra pergunta e analisar, eu posso ver o problema, acredito que tudo se resume a isso:

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

Isso gera @@ servername , e a saída desejada é o valor de @@ servername. A única maneira que eu vi fazer isso é na resposta aceita aqui

SqlACID
fonte
11
Você apenas substitui a string @@servernamepara $(dbNotServer)que o SQL enviado para execução seja SELECT @@servername AS worked. Não há atribuição do valor @@servername para a variável sqlcmd, conforme solicitado.
Martin Smith
1

Em "Saída desejada", o T-SQL indo para o servidor se torna:

SELECT '@@servername' AS worked

Colocar aspas simples @@servernamefaz com que seja uma string literal e não será substituída pelo nome real, e é por isso que você está vendo @@servernamecomo o valor.

Se você deseja exibir o nome do servidor, remova as aspas simples, criando seu T-SQL:

SELECT @@servername AS worked

Não estou totalmente claro, entendo a pergunta, mas é assim que você obteria o que está em sua "saída desejada".

Pavel
fonte