如何将多个语句传递到 sqlcmd?

Ron*_*ohn 7 scripting t-sql sqlcmd sql-server-2012

想要自动化一些任务而不是为所有事情启动 SSMS,我正在尝试编写一个批处理文件来运行这些语句,当我将它们粘贴到 sqlcmd 提示符中时,它可以完美地工作。他们只是检查镜像状态,暂停镜像,然后再次检查状态。(为了最大限度地减少依赖性并简化从一台服务器到另一台服务器的迁移,我想将所有命令保存在一个文件中。)

select cast(DB_NAME(database_id) as char(30)),
        cast(mirroring_state_desc as char(15))
from sys.database_mirroring
where mirroring_state_desc is not null;
go;

ALTER DATABASE db1 SET PARTNER SUSPEND;
ALTER DATABASE db2 SET PARTNER SUSPEND;
go;

select cast(DB_NAME(database_id) as char(30)),
        cast(mirroring_state_desc as char(15))
from sys.database_mirroring
where mirroring_state_desc is not null;
go;
Run Code Online (Sandbox Code Playgroud)

所以,我写了这个批处理文件:

SETLOCAL ENABLEDELAYEDEXPANSION
SET @SQLSTRING=select cast(DB_NAME(database_id) as char(30)), ^
        cast(mirroring_state_desc as char(15)) ^
from sys.database_mirroring ^
where mirroring_state_desc is not null; ^
go ^
^
ALTER DATABASE MSCRM_CONFIG SET PARTNER SUSPEND; ^
ALTER DATABASE XeroxGHSCRMTest_MSCRM SET PARTNER SUSPEND; ^
go ^
^
select cast(DB_NAME(database_id) as char(30)), ^
        cast(mirroring_state_desc as char(15)) ^
from sys.database_mirroring ^
where mirroring_state_desc is not null; ^
go
::
echo.
sqlcmd -S AGABQ0VMCRMDB01\PROD_CRM -E -Q "%@SQLSTRING%"
Run Code Online (Sandbox Code Playgroud)

但是,它在“go”命令中出现语法错误而失败。我试过“去”和“去”;没有运气。

任何使这项工作的提示或指导将不胜感激。

Sol*_*zky 5

这种方法有几个问题:

  1. 眼前的问题是你不能继续空行。go ^因此,只有单个字符的两行(每行后面)^导致该行结束而不是继续。它与 无关go。因此,您只需在胡萝卜之前添加一个空格即可构建完整的字符串。

  2. 然而,即使你解决了问题#1,你仍然会遇到无效的 SQL,因为它GO需要单独占一行,或者最多可选地后跟一些空格和一个 INT 值,表示重复前一个批次的次数(例如GO 12)。但是,通过使用行继续^不会有任何嵌入的返回,因此所有内容都将作为单行提交,这对于GO其中的命令来说不是有效的语法。

这给您留下了两个选择:

  1. 如果您提交的 SQL 不需要任何批处理分隔,那么只需删除GO命令(并且删除符号也不会造成伤害@,并且也不需要ENABLEDELAYEDEXPANSION和 最终):GO

    SET SQLSTRING=select cast(DB_NAME(database_id) as char(30)), ^
            cast(mirroring_state_desc as char(15)) ^
    from sys.database_mirroring ^
    where mirroring_state_desc is not null; ^
     ^
    ALTER DATABASE MSCRM_CONFIG SET PARTNER SUSPEND; ^
    ALTER DATABASE XeroxGHSCRMTest_MSCRM SET PARTNER SUSPEND; ^
     ^
    select cast(DB_NAME(database_id) as char(30)), ^
            cast(mirroring_state_desc as char(15)) ^
    from sys.database_mirroring ^
    where mirroring_state_desc is not null;
    
    ECHO.
    sqlcmd -S AGABQ0VMCRMDB01\PROD_CRM -E -Q "%SQLSTRING%"
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果您确实需要批量分离(例如,您有一个CREATE PROCEDURE语句或类似的东西),那么您可以在 CMD 脚本中创建一个 SQL 文件,单独添加每一行,然后将其用作 SQLCMD 将运行的 SQL 脚本。这允许您嵌入返回以及使用GO命令:

    @ECHO OFF
    
    ECHO. > MultiLine.sql
    ECHO select cast(DB_NAME(database_id) as char(30)), >> MultiLine.sql
    ECHO        cast(mirroring_state_desc as char(15)) >> MultiLine.sql
    ECHO from sys.database_mirroring >> MultiLine.sql
    ECHO where mirroring_state_desc is not null; >> MultiLine.sql
    ECHO GO >> MultiLine.sql
    ECHO. >> MultiLine.sql
    ECHO ALTER DATABASE MSCRM_CONFIG SET PARTNER SUSPEND; >> MultiLine.sql
    ECHO ALTER DATABASE XeroxGHSCRMTest_MSCRM SET PARTNER SUSPEND; >> MultiLine.sql
    ECHO GO >> MultiLine.sql
    ECHO. >> MultiLine.sql
    ECHO select cast(DB_NAME(database_id) as char(30)), >> MultiLine.sql
    ECHO        cast(mirroring_state_desc as char(15)) >> MultiLine.sql
    ECHO from sys.database_mirroring >> MultiLine.sql
    ECHO where mirroring_state_desc is not null; >> MultiLine.sql
    
    ECHO.
    sqlcmd -S AGABQ0VMCRMDB01\PROD_CRM -E -i MultiLine.sql
    
    Run Code Online (Sandbox Code Playgroud)

  • 选项 1 非常有效。 (2认同)