SQLCMD 模式下另一个变量内的变量

use*_*130 9 sql-server scripting sqlcmd

尝试使用 SQLCMD 模式整理我的 SQL 脚本时遇到了一个问题:

:setvar db_suffix "some_suffix"
:setvar some_db "some_db_$(db_suffix)"
print 'some_db: $(some_db)'
Run Code Online (Sandbox Code Playgroud)

其输出是:

some_db: some_db_$(db_suffix)
Run Code Online (Sandbox Code Playgroud)

然而,我的预期是:

some_db: some_db_some_suffix
Run Code Online (Sandbox Code Playgroud)

有没有办法像这样进行变量插值?

(请注意,诸如此类的 T-SQL 函数CONCAT()将不起作用,因为我将使用该变量作为数据库名称)。

Sol*_*zky 13

有没有办法像这样进行变量插值?

在某种程度上,有点像。只是不直接。

您需要牢记以下几点:

  1. 您将变量设置为 via 的:setvar值是一个简单的文字值。您可以通过运行以下两行来看到这一点:

    :setvar var1 $(var2)
    PRINT '$(var1)';
    
    Run Code Online (Sandbox Code Playgroud)

    返回:

    $(var2)
    
    Run Code Online (Sandbox Code Playgroud)

    如果 SQLCMD / SQLCMD 模式试图以:setvar任何方式解析 的值部分,那么它会在$(var2)未定义时出错。

  2. 变量代换允许在一些其他SQLCMD命令。

    例如,这意味着您可以在将 SQLCMD 变量传递给该命令行的同时执行 shell 命令:

    :setvar db_suffix some_suffix
    !! echo :setvar other_db [MyDB_$(db_suffix)] > c:\TEMP\setvar.txt
    
    Run Code Online (Sandbox Code Playgroud)

    上面的两行将创建/覆盖一个文件C:\TEMP\setvar.txt,其中的文本“:setvar other_db [MyDB_$(db_suffix)]”$(db_suffix)被替换为它的值“some_suffix”。

  3. 通过:r命令导入的文件/脚本中的 SQLCMD 命令在第二遍处理,允许在这些外部文件中设置的变量反映在主脚本中:

    :setvar db_suffix some_suffix
    !! echo :setvar other_db [MyDB_$(db_suffix)] > c:\TEMP\setvar.txt
    :r C:\TEMP\setvar.txt
    PRINT 'somethin_somethin: $(other_db)';
    
    Run Code Online (Sandbox Code Playgroud)

    返回:

    somethin_somethin: [MyDB_some_suffix]
    
    Run Code Online (Sandbox Code Playgroud)
  4. SQLCMD 命令按每个批次解释!!因此,如果您想更改连接的值,那么您需要将临时文件的每次创建和读取分开,否则您获得的值将是最后一个要设置的值,因为所有的!!:r命令都将在变量值之前处理代入,然后可以将批处理提交给 SQL Server 处理 T-SQL。例如:

    :setvar db_suffix some_suffixes
    
    !! echo :setvar other_db [MyDB_$(db_suffix)] > c:\TEMP\setvar.txt
    :r C:\TEMP\setvar.txt
    PRINT 'somethin_somethin: $(other_db)';
    
    --GO
    
    !! echo :setvar other_db [NotMyDB_$(db_suffix)22] > c:\TEMP\setvar.txt
    :r C:\TEMP\setvar.txt
    PRINT 'somethin_somethin2: $(other_db)'
    
    Run Code Online (Sandbox Code Playgroud)

    将返回:

    somethin_somethin: [NotMyDB_some_suffixes22]
    somethin_somethin2: [NotMyDB_some_suffixes22]
    
    Run Code Online (Sandbox Code Playgroud)

    但是,取消注释--GO,您将获得以下信息:

    somethin_somethin: [MyDB_some_suffixes]
    somethin_somethin2: [NotMyDB_some_suffixes22]
    
    Run Code Online (Sandbox Code Playgroud)