Режим SQLCMD в SSMS и расширение @@ переменных


8

При использовании режима SQLCMD без SSMS (не из командной строки), есть ли способ назначить текущий сервер и экземпляр переменной? Это отличается от назначения обычных переменных TSQL.

Определение проблемы

Я хочу использовать возможности расширения переменных SQLCMD для замены значений, специфичных для среды, в наших сценариях развертывания вместо существующей системы построения строк tsql, в которую я заходил. С одним исключением из текущей среды использование SQLCMD для обработки развертываний прошло очень хорошо.

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

И это приводит к следующим результатам.

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

Мясной рулет говорит, что 2 из 3 - это неплохо , но я бы предпочел решение 3 из 3. Когда этот сценарий будет развернут на тестовом сервере, я не хочу доверять пользователям развертывания редактирование сценария.

Если единственным решением для использования SQLCMD является полный запуск сценариев из командной строки, я могу согласиться с этим, но хотел бы выкинуть это здесь, так как я готов использовать SQLCMD.

Желаемый вывод

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

Результаты

worked
DEVA\DEV2

Бесплодные занятия

Первая ссылка BOL показала обещание, все, что мне нужно было сделать, это использовать SQLCMDSERVER, но безрезультатно. Запустите в контексте SSMS в режиме SQLCMD, это вызовет фатальную ошибку скриптинга

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

Обновление Tumbleweed

2011-08-12 В попытке свести мою проблему к простейшей форме, основываясь на ответах, я упростил свои запросы (мои извинения). Часть запроса, которую я использовал, приведена ниже. Два ответа правильны в своих ответах, которые определяют, что перенос @@ servername в тиковые метки приводит к буквальному значению, и чтобы получить расширенное значение, мне нужно было бы развернуть его из кавычек. Я хотел использовать подстановку переменных sqlcmd, а не сборку строк, что повлекло бы за собой развертывание строк.

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

Вызов командной строки работает (как и ожидалось)

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

Я пробовал и отказывался от других перестановок: setvar x @@ servername, пытаясь получить оцененное значение переменной базы данных, сохраненной в переменной SQLCMD. На данный момент, я вполне уверен, что переменные sqlcmd замещаются в запросах до их компиляции, но хотелось бы, чтобы их ошиблись.

BOL ссылки

Ответы:


3

Переменные SQL-CMD оцениваются до запуска пакета. Таким образом, вы не можете присвоить значение переменной t-sql CMD-переменной.


Это, конечно, так выглядит. Вам известно о какой-либо документации, подтверждающей, что это так?
billinkc

3

Если я что-то упустил, разве это не работает без апострофов?

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

Он возвращает SERVER \ INSTANCE для меня в режиме SQLCMD через SSMS.

Редактировать 12/12/2018 После того, как я нашел ответ на другой вопрос и рассмотрел его, я вижу проблему, я думаю, она сводится к следующему:

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

Это выводит @@ servername , а желаемым выводом является значение @@ servername. Единственный способ, которым я видел, это сделать в принятом ответе здесь


1
Вы просто заменить строку @@servernameдля $(dbNotServer)поэтому SQL послал выполнить это SELECT @@servername AS worked. Не присваивается значение @@servername переменной sqlcmd, как было запрошено.
Мартин Смит

1

В разделе «Требуемый вывод» T-SQL, идущий на сервер, становится:

SELECT '@@servername' AS worked

Помещение одинарных кавычек @@servernameделает его строковым литералом и не будет заменено реальным именем, поэтому вы видите его @@servernameв качестве значения.

Если вы хотите отобразить имя сервера, удалите одиночные кавычки, сделав ваш T-SQL:

SELECT @@servername AS worked

Мне не совсем понятно, я понимаю вопрос, но именно так вы получите то, что находится в вашем «желаемом результате».

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.