SSMS和@@ variable扩展中的SQLCMD模式


8

将SQLCMD模式与SSMS一起使用时(不是从命令行使用),是否可以将当前服务器和实例分配给变量?这不同于分配普通的TSQL变量。

问题定义

我想使用SQLCMD的变量扩展功能来替代我们部署脚本中的特定于环境的值,而不是我已经走进的现有tsql字符串构建mash。除了当前环境之外,使用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

Meat Loaf说3分之2不错,但我宁愿3分之3的解决方案。当该脚本被部署到测试服务器上时,我不想信任编辑脚本的部署人员。

如果使用SQLCMD的唯一​​解决方案是完全从命令行调用脚本,那么我可以接受,但由于我对使用SQLCMD持绿色态度,因此想将其抛在这里。

所需的输出

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

结果

worked
DEVA\DEV2

徒劳的追求

第一个BOL链接显示出希望,我所要做的就是使用SQLCMDSERVER,但无济于事。在SQLCMSS模式下的SSMS上下文中运行,它将引发致命的脚本错误

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

风滚草更新

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

Answers:


3

在批处理运行之前,将评估SQL-CMD变量。因此,您不能将t-sql变量值分配给CMD变量。


肯定是那样的。您是否知道任何文档说明是这样?
billinkc

3

除非我丢失了某些东西,否则如果没有撇号,这是行不通的吗?

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

它通过SSMS以SQLCMD模式为我返回SERVER \ INSTANCE。

编辑02/12/2018在遇到我对另一个问题的回答并进行审查后,我可以看到问题了,我认为它可以归结为:

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

这将输出@@ servername,并且所需的输出是@@ servername的值。我看到的唯一方法是在此处接受的答案中


1
您只需将字符串替换@@servername$(dbNotServer),即可发送执行的SQL为SELECT @@servername AS worked。没有按要求将值 赋给@@servernamesqlcmd变量。
马丁·史密斯

1

在“所需的输出”下,转到服务器的T-SQL变为:

SELECT '@@servername' AS worked

用单引号引起来@@servername会使它成为字符串文字,并且不会被实际名称替换,这就是为什么您将其@@servername视为值。

如果要显示服务器名称,请删除单引号,以进行T-SQL:

SELECT @@servername AS worked

我尚不清楚我理解这个问题,但是这就是您将如何获得“所需输出”中的内容的方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.