为什么SQLCMD模式在连接其他服务器时好像执行xp_cmdshell乱序?

Why does SQLCMD mode seem to execute xp_cmdshell out of sequence when connecting to other servers?

如果我连接到服务器“ServerA.domain.com”并在 SQLManagement Studio 的 SQLCMD 模式下执行以下命令:

EXEC xp_cmdshell 'hostname'
:CONNECT ServerB.domain.com
EXEC xp_cmdshell 'hostname'

则输出为:

Connecting to ServerB.domain.com...
output
---------------------------------------
ServerB
NULL

(2 rows affected)

output
------------------------------------------
ServerB
NULL

(2 rows affected)

Disconnecting connection from ServerB.domain.com...

它似乎在第一个 xp_cmdshell 命令之前执行 :CONNECT 命令,尽管脚本的顺序是这样。这是什么原因,可以预防吗?

sqlcmd Commands 文档中看并不明显,但确实提供了提示:

Commands are executed immediately. They are not put in the execution buffer as Transact-SQL statements are.

这里的含义是与下面的 .sql 文件:

EXEC xp_cmdshell 'hostname'
:CONNECT ServerB.domain.com
EXEC xp_cmdshell 'hostname'

首先执行 :CONNECT ServerB.domain.com,然后执行两个缓冲语句 EXEC xp_cmdshell 'hostname',这与您看到的行为相关。

要获得预期的行为,您需要添加 GO 批处理分隔符:

EXEC xp_cmdshell 'hostname'
GO
:CONNECT ServerB.domain.com
EXEC xp_cmdshell 'hostname'