sqlcmd 实用工具

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse AnalyticsAnalytics Platform System (PDW)

可以通过各种模式,使用 sqlcmd 实用工具输入 Transact-SQL 语句、系统过程和脚本文件:

  • 通过命令提示符。
  • 在查询编辑器中的 SQLCMD 模式下。
  • 在 Windows 脚本文件中。
  • 在 SQL Server 代理作业的操作系统 (cmd.exe) 作业步骤中。

注意

虽然 Microsoft Entra ID 是 Azure Active Directory (Azure AD) 的新名称,但为了防止中断现有环境,Azure AD 仍保留在一些硬编码的元素中,例如 UI 字段、连接提供程序、错误代码和 cmdlet。 在本文中,这两个名称可以互换。

查找安装的版本

sqlcmd 有两个版本:

  • 基于 go-mssqldb 的 sqlcmd,有时样式为 go-sqlcmd。 此版本是可以独立于 SQL Server 下载的独立工具。

  • 基于 ODBC 的 sqlcmd,可用于 SQL Server 或 Microsoft 命令行实用程序,以及 Linux 上 mssql-tools 包的一部分。

若要确定已安装的版本,请在命令行中运行以下语句:

sqlcmd "-?"
sqlcmd "-?"
sqlcmd -?

如果使用新版本的 sqlcmd (Go),输出类似于以下示例:

Version: 1.3.1

检查版本

可以使用 sqlcmd --version 确定安装了哪个版本。 应至少安装版本 1.0.0。

注意

对于 SQL Server 2014 (12.x) 和早期版本,请参阅 sqlcmd 实用工具

有关在 Linux 上使用 sqlcmd 的信息,请参阅在 Linux 上安装 sqlcmd 和 bcp

重要

如果通过包管理器安装 sqlcmd (Go),会在环境路径中将 sqlcmd (ODBC) 替换为 sqlcmd (Go)。 需要关闭任何当前命令行会话,再将它们重新打开,才能使此操作生效。 不会移除 sqlcmd (ODBC),仍可通过指定可执行文件的完整路径来使用它。 还可更新 PATH 变量来指示优先使用哪一个。 若要在 Windows 11 中执行此操作,请打开“系统设置”,然后转到“关于”>“高级系统设置”。 打开“系统属性”时,选择“环境变量”按钮。 在下半部分的“系统变量”下,选择“路径”,然后选择“编辑”。 如果 sqlcmd (Go) 保存到 C:\Program Files\Microsoft SQL Server\<version>\Tools\Binn 前面列出的 C:\Program Files\sqlcmd(默认位置),则使用 sqlcmd (Go)。 可以颠倒顺序,使 sqlcmd (ODBC) 再次成为默认值。

下载并安装 sqlcmd

sqlcmd (Go) 可以在 Microsoft Windows、macOS 和 Linux 上跨平台安装。

winget(Windows 包管理器 CLI)

  1. 请安装 Windows 包管理器客户端(如果尚未安装)。

  2. 运行以下命令以安装 sqlcmd (Go)。

    winget install sqlcmd
    

Chocolatey

  1. 安装 Chocolatey(如果尚未安装)。

  2. 运行以下命令以安装 sqlcmd (Go)。

    choco install sqlcmd
    

直接下载

  1. 从 GitHub 代码存储库下载最新版本的 sqlcmd (Go) 中的相应 -windows-x64.zip-windows-arm.zip 资产。

  2. 从下载的 zip 文件夹中提取 sqlcmd.exe 文件。

已预安装

Azure Cloud Shell

可以从 Azure Cloud Shell 中尝试使用 sqlcmd 实用工具,因为它在默认情况下已预安装:

Azure Data Studio

若要在 Azure Data Studio 中运行 SQLCMD 语句,请从编辑器工具栏中选择“启用 SQLCMD”

SQL Server Management Studio (SSMS)

若要在 SQL Server Management Studio (SSMS) 中运行 SQLCMD 语句,请从顶部导航栏上的“查询菜单”下拉列表中选择“SQLCMD 模式”。

在“查询编辑器”的常规模式和 SQLCMD 模式下,SSMS 使用 Microsoft .NET Framework SqlClient 执行操作。 通过命令行运行 sqlcmd 时,sqlcmd 使用 ODBC 驱动程序。 由于可以应用不同的默认选项,因此在 SSMS 中在 SQLCMD 模式下以及在 sqlcmd 实用工具中执行相同的查询时,可能会看到不同的行为。

语法

Usage:
  sqlcmd [flags]
  sqlcmd [command]

Examples:
# Install/Create, Query, Uninstall SQL Server
  sqlcmd create mssql --accept-eula --using https://aka.ms/AdventureWorksLT.bak
  sqlcmd open ads
  sqlcmd query "SELECT @@version"
  sqlcmd delete
# View configuration information and connection strings
  sqlcmd config view
  sqlcmd config cs

Available Commands:
  completion  Generate the autocompletion script for the specified shell
  config      Modify sqlconfig files using subcommands like "sqlcmd config use-context mssql"
  create      Install/Create SQL Server, Azure SQL, and Tools
  delete      Uninstall/Delete the current context
  help        Help about any command
  open        Open tools (e.g ADS) for current context
  query       Run a query against the current context
  start       Start current context
  stop        Stop current context

Flags:
  -?, --?                  help for backwards compatibility flags (-S, -U, -E etc.)
  -h, --help               help for sqlcmd
      --sqlconfig string   configuration file (default "/Users/<currentUser>/.sqlcmd/sqlconfig")
      --verbosity int      log level, error=0, warn=1, info=2, debug=3, trace=4 (default 2)
      --version            print version of sqlcmd

Use "sqlcmd [command] --help" for more information about a command.

若要深入了解 sqlcmd 语法和用法,请参阅 ODBC sqlcmd 语法

sqlcmd (ODBC) 的中断性变更

在 sqlcmd (Go) 实用程序中,一些开关和行为发生了改变。 有关后向兼容性的缺失标志的最新列表,请参阅优先实现后向兼容性标志 GitHub 讨论。

  • 在早期版本的 sqlcmd (Go) 中,-P 开关已暂时移除,并且只能通过以下机制提供 SQL Server 身份验证的密码:

    • SQLCMDPASSWORD 环境变量
    • :CONNECT 命令
    • 出现提示时,用户可以键入密码以完成连接
  • -r 需要 01 参数

  • 删除了 -R 开关。

  • 删除了 -I 开关。 若要禁用带引号的标识符行为,请在脚本中添加 SET QUOTED IDENTIFIER OFF

  • -N 现在需要一个字符串值,可以是 truefalsedisable 之一,以指定加密选择。 (default 与省略该参数的行为相同)

    • 如果没有提供 -N-C,sqlcmd 将与服务器协商身份验证,而不验证服务器证书。
    • 如果提供了 -N 但没有提供 -C,则 sqlcmd 需要验证服务器证书。 如果加密值为 false,仍可能导致登录数据包加密。
    • 如果同时提供了 -N-C,sqlcmd 将使用其值进行加密协商。
    • 有关客户端/服务器加密协商的详细信息,请参阅 MS-TDS PRELOGINMS-TDS PRELOGIN
  • -u 生成的 Unicode 输出文件会将 UTF-16 Little-Endian 字节顺序标记 (BOM) 写入其中。

  • 为了保持与 OSQL 的兼容性而保留的一些行为可能会发生更改,例如某些数据类型的列标题对齐方式。

  • 所有的命令必须放在一行,甚至包括 EXIT。 交互模式不会检查命令的左括号或引号,并且不会提示存在连续行。 此行为与 ODBC 版本不同,该版本允许查询通过 EXIT(query) 跨多行运行。

sqlcmd (Go) 实用程序的连接仅限于 TCP 连接。 go-mssqldb 驱动程序目前不支持命名管道。

增强功能

  • :Connect 现在有一个可选的 -G 参数,用于为 Azure SQL 数据库选择一种身份验证方法 - SqlAuthenticationActiveDirectoryDefaultActiveDirectoryIntegratedActiveDirectoryServicePrincipalActiveDirectoryManagedIdentityActiveDirectoryPassword。 有关详细信息,请参阅 Microsoft Entra 身份验证。 如果没有提供 -G,将使用集成安全性或 SQL Server 身份验证,具体取决于是否存在 -U 用户名参数。

  • 使用新的 --driver-logging-level 命令行参数,可以查看来自 go-mssqldb 驱动程序的跟踪。 使用 64 可查看所有跟踪。

  • sqlcmd 现在可以使用垂直格式打印结果。 使用新的 -F vertical 命令行开关对其进行设置。 它还受到 SQLCMDFORMAT 脚本变量的控制。

命令行选项

-A

使用专用管理员连接 (DAC) 登录 SQL Server。 此类型连接用于排除服务器故障。 此连接只适用于支持 DAC 的服务器计算机。 如果 DAC 不可用,sqlcmd 会生成错误消息并退出。 有关 DAC 的详细信息,请参阅 用于数据库管理员的诊断连接。 不支持同时使用 -A 选项和 -G 选项。 使用 -A 连接到 Azure SQL 数据库时,你必须是逻辑 SQL 服务器的管理员。 DAC 不适用于 Microsoft Entra 管理员。

C-

该选项供客户端用于将其配置为隐式表示信任服务器证书且无需验证。 此选项等同于 ADO.NET 选项 TRUSTSERVERCERTIFICATE = true

对于 sqlcmd (Go) 实用程序,以下条件也适用:

  • 如果没有提供 -N-C,sqlcmd 将与服务器协商身份验证,而不验证服务器证书。
  • 如果提供了 -N 但没有提供 -C,则 sqlcmd 需要验证服务器证书。 如果加密值为 false,仍可能导致登录数据包加密。
  • 如果同时提供了 -N-C,sqlcmd 将使用其值进行加密协商。

-d db_name

启动 sqlcmd 时发出一个 USE <db_name> 语句。 此选项设置 sqlcmd 脚本变量 SQLCMDDBNAME。 此参数指定初始数据库。 默认为你的登录名的默认数据库属性。 如果数据库不存在,则生成错误消息且 sqlcmd 退出。

-d

将提供给 -S 的服务器名称解释为 DSN 而不是主机名。 有关详细信息,请参阅使用 sqlcmd 进行连接中的“sqlcmd 和 bcp 中的 DSN 支持”。

注意

-D 选项仅适用于 Linux 和 macOS 客户端。 在 Windows 客户端上,它以前引用的选项现在已过时,该选项已被删除并被忽略。

-l login_timeout

指定在你尝试连接到服务器时 sqlcmd 登录 ODBC 驱动程序的超时时间(以秒为单位)。 此选项设置 sqlcmd 脚本变量 SQLCMDLOGINTIMEOUT。 登录到 sqlcmd 的默认超时时间为 8 秒。 使用 -G 选项连接到 Azure SQL 数据库或 Azure Synapse Analytics,并使用 Microsoft Entra ID 进行身份验证时,建议超时值至少为 30 秒。 登录超时必须是介于 065534 之间的数字。 如果提供的值不是数值或不在此范围内,则 sqlcmd 将生成错误消息。 该值为 0 时,则允许无限制等待。

-E

使用信任连接而不是用户名和密码登录 SQL Server。 默认情况下,如果未指定 -Esqlcmd 将使用信任连接选项。

-E 选项会忽略可能的用户名和密码环境变量设置,例如 SQLCMDPASSWORD。 如果将 -E 选项与 -U 选项或 -P 选项一起使用,将生成错误消息。

-g

将列加密设置设为 Enabled。 有关详细信息,请参阅 Always Encrypted。 仅支持存储在 Windows 证书存储中的主密钥。 -g 选项至少需要 sqlcmd 版本 13.1。 若要确定你的版本,请执行 sqlcmd -?

-G

连接到 Azure SQL 数据库或 Azure Synapse Analytics 时,客户端将使用此选项指定该用户使用 Microsoft Entra 身份验证来进行身份验证。 此选项设置 sqlcmd 脚本变量 SQLCMDUSEAAD = true-G 选项至少需要 sqlcmd 版本 13.1。 若要确定你的版本,请执行 sqlcmd -?。 有关详细信息,请参阅使用 Microsoft Entra 身份验证连接到 SQL 数据库或 Azure Synapse Analytics。 不支持同时使用 -A 选项和 -G 选项。

-G 选项仅适用于 Azure SQL 数据库和 Azure Synapse Analytics。

Linux 或 macOS 目前不支持 Microsoft Entra 交互式身份验证。 Microsoft Entra 集成身份验证需要 Microsoft ODBC Driver 17 for SQL Server 版本 17.6.1 或更高版本,以及正确配置的 Kerberos 环境

有关进行 Microsoft Entra 身份验证的详细信息,请参阅在 sqlcmd 中进行 Microsoft Entra 身份验证

-H workstation_name

工作站的名称。 此选项设置 sqlcmd 脚本变量 SQLCMDWORKSTATION。 工作站名称列在 sys.sysprocesses 目录视图的 hostname 列中,并且可使用存储过程 sp_who 返回工作站名称。 如果不指定此选项,则默认为当前计算机名称。 此名称可用来标识不同的 sqlcmd 会话。

-j

将原始错误消息输出到屏幕上。

-K application_intent

连接到服务器时声明应用程序工作负荷类型。 目前唯一支持的值是 ReadOnly。 如果未指定 -K,sqlcmd 将不支持连接到可用性组中的次要副本。 有关详细信息,请参阅活动次要副本:可读次要副本(AlwaysOn 可用性组)

-M multisubnet_failover

在连接到 SQL Server 可用性组或 SQL Server 故障转移群集实例的可用性组侦听程序时,应始终指定 -M-M 将为(当前)活动服务器提供更快的检测和连接。 如果未指定 -M,则 -M 处于关闭状态。 有关详细信息,请参阅侦听程序、客户端连接、应用程序故障转移创建和配置可用性组 (SQL Server)故障转移群集和 AlwaysOn 可用性组 (SQL Server)活动次要副本:可读次要副本(AlwaysOn 可用性组)

-N

此选项供客户端用于请求加密连接。

对于 sqlcmd (Go) 实用程序,-N 现在需要一个字符串值,可以是 truefalsedisable 之一,以指定加密选择。 (default 与省略该参数的行为相同):

  • 如果没有提供 -N-C,sqlcmd 将与服务器协商身份验证,而不验证服务器证书。
  • 如果提供了 -N 但没有提供 -C,则 sqlcmd 需要验证服务器证书。 如果加密值为 false,仍可能导致登录数据包加密。
  • 如果同时提供了 -N-C,sqlcmd 将使用其值进行加密协商。

-P password

用户指定的密码。 密码是区分大小写的。 如果使用了 -U 选项而未使用 -P 选项,并且未设置 SQLCMDPASSWORD 环境变量,则 sqlcmd 会提示用户输入密码。 我们不建议使用 null(空)密码,但你可以通过对参数值 ("") 使用一对连续的双引号来指定 null 密码。

重要

使用 -P 应该被视为不安全的做法。 请避免在命令行上提供密码。 或者使用 SQLCMDPASSWORD 环境变量或通过省略 -P 选项以交互方式输入密码。

建议使用强密码

通过向控制台输出密码提示,可以显示密码提示,如下所示: Password:

隐藏用户输入。 也就是说,将不会显示任何输入的内容,光标保留原位不动。

使用 SQLCMDPASSWORD 环境变量可以为当前会话设置默认密码。 因此,不必将密码硬编码到批处理文件中。 以下示例首先在命令提示符处设置 SQLCMDPASSWORD 变量,然后访问 sqlcmd 实用工具。

在命令提示符处,键入:

SET SQLCMDPASSWORD=p@a$$w0rd
sqlcmd
SET SQLCMDPASSWORD=p@a$$w0rd
sqlcmd
SET SQLCMDPASSWORD=p@a$$w0rd
sqlcmd

如果用户名和密码组合不正确,将生成错误消息。

备注

为实现后向兼容性而保留了 OSQLPASSWORD 环境变量。 SQLCMDPASSWORD 环境变量优先于 OSQLPASSWORD 环境变量。 也就是说, sqlcmdosql 可以彼此相邻使用而不会相互干扰。 旧脚本可以继续使用。

如果将 -P 选项与 -E 选项一起使用,将生成错误消息。

如果 -P 选项后有多个参数,将生成错误消息并退出程序。

包含特殊字符的密码可以生成错误消息。 使用 -P 时应转义特殊字符,或改为使用 SQLCMDPASSWORD 环境变量。

-S [protocol:]server[\instance_name][,port]

指定要连接到的 SQL Server 实例。 它设置 sqlcmd 脚本变量 SQLCMDSERVER

指定 server_name 可连接到该服务器计算机上的 SQL Server 默认实例。 指定要连接到该服务器计算机上 SQL Server 命名实例的 server_name[\instance_name]。 如果不指定服务器,sqlcmd 将连接到本地计算机上 SQL Server 的默认实例。 从网络上的远程计算机执行 sqlcmd 时,此选项是必需的。

protocol 可以是 tcp (TCP/IP)、 lpc (共享内存)或 np (命名管道)。

如果在启动 sqlcmd 时未指定 server_name[\instance_name],SQL Server 将检查并使用 SQLCMDSERVER 环境变量。

注意

为实现后向兼容性而保留了 OSQLSERVER 环境变量。 SQLCMDSERVER 环境变量优先于 OSQLSERVER 环境变量。 也就是说, sqlcmdosql 可以彼此相邻使用而不会相互干扰。 旧脚本可以继续使用。

-U login_id

登录名或包含的数据库用户名。 对于包含的数据库用户,必须提供数据库名称选项 (-d)。

注意

为实现后向兼容性而保留了 OSQLUSER 环境变量。 SQLCMDUSER 环境变量优先于 OSQLUSER 环境变量。 也就是说, sqlcmdosql 可以彼此相邻使用而不会相互干扰。 旧脚本可以继续使用。

如果未指定 -U 选项或 -P 选项,sqlcmd 会尝试使用 Windows 身份验证模式进行连接。 身份验证基于运行 sqlcmd 的用户的 Windows 帐户。

如果 -U 选项与 -E 选项(将在本主题的后面进行说明)一起使用,则会生成错误消息。 如果 -U 选项后有多个参数,将生成错误消息并退出程序。

-z new_password

更改密码:

sqlcmd -U someuser -P s0mep@ssword -z a_new_p@a$$w0rd
sqlcmd -U someuser -P s0mep@ssword -z a_new_p@a$$w0rd
sqlcmd -U someuser -P s0mep@ssword -z a_new_p@a$$w0rd

-Z new_password

更改密码并退出:

sqlcmd -U someuser -P s0mep@ssword -Z a_new_p@a$$w0rd
sqlcmd -U someuser -P s0mep@ssword -Z a_new_p@a$$w0rd
sqlcmd -U someuser -P s0mep@ssword -Z a_new_p@a$$w0rd

输入/输出选项

-f codepage | i:codepage[,o:codepage] | o:codepage[,i:codepage]

指定输入和输出代码页。 代码页页码是指定已安装的 Windows 代码页的数值。

代码页转换规则:

  • 如果未指定代码页,sqlcmd 会将当前代码页同时用于输入文件和输出文件,除非输入文件为 Unicode 文件,在此情况下无需进行转换。

  • sqlcmd 自动识别 Big-endian Unicode 和 Little-endian Unicode 输入文件。 如果已指定 -u 选项,输出始终为 Little-endian Unicode。

  • 如果未指定输出文件,输出代码页为控制台代码页。 借助此方法,可以在控制台上正确显示输出。

  • 假定多个输入文件具有相同的代码页。 可以将 Unicode 和非 Unicode 输入文件混合在一起。

在命令提示符处输入 chcp 以验证 cmd.exe 的代码页。

-i input_file[,input_file2...]

标识包含一批 Transact-SQL 语句或存储过程的文件。 可以指定按顺序读取和处理的多个文件。 文件名之间不要使用任何空格。 sqlcmd 首先检查所有指定的文件是否都存在。 如果有一个或多个文件不存在,sqlcmd 将退出。 -i-Q/-q 选项互斥。

路径示例:

-i C:\<filename>
-i \\<Server>\<Share$>\<filename>
-i "C:\Some Folder\<file name>"

包含空格的文件路径必须用引号引起来。

此选项可能多次使用:

sqlcmd -i <input_file1> -i <input_file2>
sqlcmd -i <input_file1> -i <input_file2>
sqlcmd -i <input_file1> -i <input_file2>

-o output_file

标识从 sqlcmd 接收输出的文件。

如果指定了 -u ,则 output_file 以 Unicode 格式存储。 如果文件名无效,将生成一个错误消息,并且 sqlcmd 将退出。 sqlcmd 不支持向同一文件并发写入多个 sqlcmd 进程。 文件输出损坏或不正确。 -f 选项还与文件格式相关。 如果不存在,则将创建此文件。 前一个 sqlcmd 会话中的同名文件将被覆盖。 此处指定的文件不是 stdout 文件。 如果指定了 stdout 文件,则不使用此文件。

路径示例:

-o C:< filename>
-o \\<Server>\<Share$>\<filename>
-o "C:\Some Folder\<file name>"

包含空格的文件路径必须用引号引起来。

-r[0 | 1]

将错误消息输出重定向到屏幕 (stderr)。 如果未指定参数或指定参数为 0,则仅重定向严重级别为 11 或更高的错误消息。 如果指定参数为 1,则将重定向所有消息输出(包括 PRINT)。 如果使用 -o,则此选项不起作用。 默认情况下,消息将发送到 stdout

注意

对于 sqlcmd (Go) 实用程序,-r 需要 01 自变量。

-R

仅适用于: ODBC sqlcmd

让 sqlcmd 根据客户端的区域设置,本地化从 SQL Server 中检索到的数字、货币、日期和时间列。 默认情况下,这些列使用服务器的区域设置进行显示。

-U

指定无论 input_file 为何种格式,都以 Unicode 格式存储 output_file

注意

对于 sqlcmd (Go) 实用程序,生成的 Unicode 输出文件会将 UTF-16 Little-Endian 字节顺序标记 (BOM) 写入其中。

查询执行选项

-E

将输入脚本写入标准输出设备 (stdout)。

-I

仅适用于: ODBC sqlcmd

SET QUOTED_IDENTIFIER 连接选项设置为 ON。 默认情况下它设置为 OFF。 有关详细信息,请参阅 SET QUOTED_IDENTIFIER (Transact-SQL)

注意

若要在 sqlcmd (Go) 实用程序中禁用带引号的标识符行为,请在脚本中添加 SET QUOTED IDENTIFIER OFF

-q "cmdline query"

启动 sqlcmd 时执行查询,但是在查询结束运行时不退出 sqlcmd。 可以执行多个以分号分隔的查询。 将查询用引号引起来,如下例所示。

在命令提示符处,键入:

sqlcmd -d AdventureWorks2022 -q "SELECT FirstName, LastName FROM Person.Person WHERE LastName LIKE 'Whi%';"

sqlcmd -d AdventureWorks2022 -q "SELECT TOP 5 FirstName FROM Person.Person;SELECT TOP 5 LastName FROM Person.Person;"
sqlcmd -d AdventureWorks2022 -q "SELECT FirstName, LastName FROM Person.Person WHERE LastName LIKE 'Whi%';"

sqlcmd -d AdventureWorks2022 -q "SELECT TOP 5 FirstName FROM Person.Person;SELECT TOP 5 LastName FROM Person.Person;"
sqlcmd -d AdventureWorks2022 -q "SELECT FirstName, LastName FROM Person.Person WHERE LastName LIKE 'Whi%';"

sqlcmd -d AdventureWorks2022 -q "SELECT TOP 5 FirstName FROM Person.Person;SELECT TOP 5 LastName FROM Person.Person;"

重要

请不要在查询中使用 GO 终止符。

如果在指定此选项的同时还指定了 -bsqlcmd 在遇到错误时将退出。 -b 将在本文其他部分进行介绍。

-Q "cmdline query"

sqlcmd 启动时执行查询,随后立即退出 sqlcmd。 可以执行多个以分号分隔的查询。

将查询用引号引起来,如下例所示。

在命令提示符处,键入:

sqlcmd -d AdventureWorks2022 -Q "SELECT FirstName, LastName FROM Person.Person WHERE LastName LIKE 'Whi%';"

sqlcmd -d AdventureWorks2022 -Q "SELECT TOP 5 FirstName FROM Person.Person;SELECT TOP 5 LastName FROM Person.Person;"
sqlcmd -d AdventureWorks2022 -Q "SELECT FirstName, LastName FROM Person.Person WHERE LastName LIKE 'Whi%';"

sqlcmd -d AdventureWorks2022 -Q "SELECT TOP 5 FirstName FROM Person.Person;SELECT TOP 5 LastName FROM Person.Person;"
sqlcmd -d AdventureWorks2022 -Q "SELECT FirstName, LastName FROM Person.Person WHERE LastName LIKE 'Whi%';"

sqlcmd -d AdventureWorks2022 -Q "SELECT TOP 5 FirstName FROM Person.Person;SELECT TOP 5 LastName FROM Person.Person;"

重要

请不要在查询中使用 GO 终止符。

如果在指定此选项的同时还指定了 -bsqlcmd 在遇到错误时将退出。 -b 将在本文其他部分进行介绍。

-t query_timeout

指定命令(或 Transact-SQL 语句)超时的时间。此选项设置 sqlcmd 脚本变量 SQLCMDSTATTIMEOUT。 如果未指定 query_timeout 值,则命令不会超时。query_timeout 必须是介于 165534 之间的数字。 如果提供的值不是数值或不在此范围内,则 sqlcmd 将生成错误消息。

注意

实际的超时值可能会与指定的 query_timeout 值相差几秒。

-v var = value [ var = value... ]

创建可在 sqlcmd 脚本中使用的 sqlcmd 脚本变量。 如果该值包含空格,则将其用引号引起来。 你可以指定多个 <var>="<value>" 值。 如果指定的任何值中有错误, sqlcmd 会生成错误消息,然后退出。

sqlcmd -v MyVar1=something MyVar2="some thing"

sqlcmd -v MyVar1=something -v MyVar2="some thing"
sqlcmd -v MyVar1=something MyVar2="some thing"

sqlcmd -v MyVar1=something -v MyVar2="some thing"
sqlcmd -v MyVar1=something MyVar2="some thing"

sqlcmd -v MyVar1=something -v MyVar2="some thing"

-X

导致 sqlcmd 忽略脚本变量。 如果脚本中包含多个 INSERT 语句,且这些语句可能包含格式与常规变量(如 $(<variable_name>))相同的字符串,就会发现此参数很有用。

格式选项

-h headers

指定要在列标题之间输出的行数。 默认为每一组查询结果输出一次标题。 此选项设置 sqlcmd 脚本变量 SQLCMDHEADERS。 使用 -1 指定不要打印的标题。 任何无效的值都将导致 sqlcmd 生成错误消息并随后退出。

-k [1 | 2]

删除输出中的所有控制字符,例如制表符和换行符。 此参数在返回数据时保留列格式。

  • -k 移除控制字符。
  • -k1 将每个控制字符替换为空格。
  • -k2 将连续的控制字符替换为单个空格。

-s col_separator

指定列分隔符字符。 默认为空格。 此选项设置 sqlcmd 脚本变量 SQLCMDCOLSEP。 若要使用对操作系统有特殊含义的字符,如“与”符号 (&) 或分号 (;),请将该字符用双引号 (") 引起来。 列分隔符可以是任意 8 位字符。

-w screen_width

指定用于输出的屏幕宽度。 此选项设置 sqlcmd 脚本变量 SQLCMDCOLWIDTH。 该列宽必须是介于 865536 之间的数字。 如果指定的列宽不在此范围内,sqlcmd 就会生成错误消息。 默认宽度为 80 个字符。 在输出行超出指定的列宽时,将转到下一行。

-w

此选项删除列的尾随空格。 在准备要导出到另一应用程序的数据时,请将此选项和 -s 选项一起使用。 不能与 -y-Y 选项一起使用。

-y variable_length_type_display_width

设置 sqlcmd 脚本变量 SQLCMDMAXVARTYPEWIDTH。 默认为 256。 它限制为下列大型可变长度数据类型返回的字符的数目:

  • varchar(max)
  • nvarchar(max)
  • varbinary(max)
  • xml
  • 用户定义的数据类型 (UDT)
  • text
  • ntext
  • 图像

根据实现,UDT 可以使用固定的长度。 如果此固定长度 UDT 的长度比 display_width 短,则返回的 UDT 值将不受影响。 但是,如果此长度比 display_width 长,则输出会被截断。

注意

使用 -y 0 选项时要特别注意,因为根据返回的数据大小,此选项可能导致服务器和网络上出现严重性能问题。

-Y fixed_length_type_display_width

设置 sqlcmd 脚本变量 SQLCMDMAXFIXEDTYPEWIDTH。 默认值为 0(无限制)。 它限制为以下数据类型返回的字符数:

  • char(n),其中 1 <= n<= 8000
  • nchar(n),其中 1 <= n<= 4000
  • varchar(n),其中 1 <= n<= 8000
  • nvarchar(n),其中 1 <= n<= 4000
  • varbinary(n),其中 1 <= n<= 4000
  • sql_variant

错误报告选项

-b

指定发生错误时,sqlcmd 退出并返回一个 DOS ERRORLEVEL 值。 当 SQL Server 错误消息的严重级别高于 10 时,返回给 ERRORLEVEL 变量的值为 1;否则返回的值为 0。 如果除 -b 选项外还设置了 -V 选项,则当严重性级别低于使用 -V 设置的值时,sqlcmd 不报告错误。 命令提示符批处理文件可以测试 ERRORLEVEL 的值并相应处理错误。 sqlcmd 不对严重级别 10 报告错误(信息性消息)。

如果 sqlcmd 脚本包含错误的注释、语法错误或缺少脚本变量,则返回的 ERRORLEVEL1

-m error_level

控制将哪些错误消息发送到 stdout。 将发送严重级别大于或等于此级别的消息。 如果此值设置为 -1,将发送所有消息(包括信息性消息)。 在 -m-1 之间不允许有空格。 例如,-m-1 有效,而 -m -1 无效。

此选项还设置 sqlcmd 脚本变量 SQLCMDERRORLEVEL。 此变量的默认值为 0

-V error_severity_level

控制用于设置 ERRORLEVEL 变量的严重级别。 严重级别大于或等于此值的错误消息将设置 ERRORLEVEL。 小于 0 的值将报告为 0。 可以使用批处理文件和 CMD 文件来测试 ERRORLEVEL 变量的值。

杂项选项

-a packet_size

需要不同大小的数据包。 此选项设置 sqlcmd 脚本变量 SQLCMDPACKETSIZE。 packet_size 必须是介于 51232767 之间的值。 默认为 4096。 如果脚本的两个 GO 命令之间包含大量 Transact-SQL 语句,则使用较大的数据包可以提高脚本执行的性能。 你可以请求更大的包大小。 但是,如果请求遭拒绝, sqlcmd 将对包大小使用服务器默认值。

-c batch_terminator

指定批处理终止符。 默认情况下,通过单独在一行中键入 GO 来终止命令并将其发送到 SQL Server。 重置批处理终止符时,不要使用对操作系统具有特殊意义的 Transact-SQL 保留关键字或字符,即便它们前面有反斜杠也是如此。

-L[c]

列出本地配置的服务器计算机和在网络上播发的服务器计算机的名称。 此参数不能与其他参数结合使用。 可以列出的服务器的最大数目是 3000。 如果服务器列表由于缓冲区大小而被截断,则会显示错误消息。

备注

鉴于网络广播的特点, sqlcmd 不可能及时接收来自所有服务器的响应。 因此,每次调用该选项所返回的服务器列表都可能不同。

如果指定了可选参数 c,输出就不会包含 Servers: 标题行,且列出的每个服务器行都没有前导空格。 此演示文稿被称为清除输出。 清除输出可以提高脚本语言的处理性能。

-p[1]

输出每个结果集的性能统计信息。 下面的输出显示示例展示了性能统计信息的格式:

Network packet size (bytes): n

x xact[s]:

Clock Time (ms.): total       t1  avg       t2 (t3 xacts per sec.)

其中:

  • x = SQL Server 处理的事务数。
  • t1 = 所有事务的总时间。
  • t2 = 单个事务的平均时间。
  • t3 = 每秒平均事务数。

所有时间均以毫秒表示。

如果指定了可选参数 1 ,则统计信息的输出格式为以冒号分隔的格式,此格式可以由脚本轻松导入到电子表格中或进行处理。

如果可选参数是除 1之外的任何值,则将生成错误并且 sqlcmd 将退出。

-X[1]

从批处理文件执行 sqlcmd 时,将禁用可能危及系统安全的命令。 禁用的命令仍然可以被识别; sqlcmd 发出警告消息并继续。 如果指定了可选参数 1 ,则 sqlcmd 将生成错误消息,然后退出。 使用 -X 选项时,将禁用以下命令:

  • ED
  • !!命令

如果指定 -X 选项,它会阻止将环境变量传递给 sqlcmd。 同时该选项还会阻止执行通过使用 SQLCMDINI 脚本变量指定的启动脚本。 有关 sqlcmd 脚本变量的详细信息,请参阅 sqlcmd - 与脚本变量结合使用

-?

显示 sqlcmd 的版本和 sqlcmd 选项的语法摘要。

注意

在 macOS 上,改为运行 sqlcmd '-?'(带引号)。

注解

不必按语法部分所示的顺序使用选项。

在返回多个结果时, sqlcmd 在批处理中的每个结果集之间输出一个空行。 此外,如果没有应用于已执行的语句,则不会出现 <x> rows affected 消息。

若要交互使用 sqlcmd,请在命令提示符处使用本文前面介绍的一个或多个选项键入 sqlcmd。 有关详细信息,请参阅 使用 sqlcmd 实用工具

注意

选项 -l-Q-Z-i 会导致 sqlcmd 在执行后退出。

命令环境(例如 cmd.exebash)中的 sqlcmd 命令行的总长度(包括所有参数和扩展变量)取决于底层操作系统。

变量优先级(从低到高)

  1. 系统级环境变量
  2. 用户级环境变量
  3. 运行 sqlcmd 之前在命令提示符处设置的命令 shell (SET X=Y)
  4. sqlcmd -v X=Y
  5. :Setvar X Y

注意

若要查看环境变量,请在“控制面板”中打开“系统”,然后选择“高级”选项卡。

sqlcmd 脚本变量

变量 相关选项 R/W 默认
SQLCMDUSER -U R “”
SQLCMDPASSWORD -P -- “”
SQLCMDSERVER sqlcmd R "DefaultLocalInstance"
SQLCMDWORKSTATION -H R "ComputerName"
SQLCMDDBNAME -d R “”
SQLCMDLOGINTIMEOUT -l R/W "8"(秒)
SQLCMDSTATTIMEOUT -t R/W "0" = 无限期等待
SQLCMDHEADERS -H R/W "0"
SQLCMDCOLSEP -S R/W “ ”
SQLCMDCOLWIDTH -w R/W "0"
SQLCMDPACKETSIZE -a R "4096"
SQLCMDERRORLEVEL -M R/W 0
SQLCMDMAXVARTYPEWIDTH -y R/W "256"
SQLCMDMAXFIXEDTYPEWIDTH -y R/W "0" = 无限制
SQLCMDEDITOR R/W "edit.com"
SQLCMDINI R “”
SQLCMDUSEAAD -G R/W “”

使用 :Connect 时,设置 SQLCMDUSERSQLCMDPASSWORDSQLCMDSERVER

R 表示在程序初始化过程中只能设置一次值。

R/W 表示可以使用 :setvar 命令修改值,并且后续命令受新值的影响。

sqlcmd 命令

除 sqlcmd 中的 Transact-SQL 语句之外,还可使用以下命令:

GO [ count ]

:List

[:]RESET

:Error

[:]ED

:Out

[:]!!

:Perftrace

[:]QUIT

:Connect

[:]EXIT

:On Error

:r

:Help

:ServerList

:XML [ ON | OFF ]

:Setvar

:Listvar

使用 sqlcmd 命令时,请注意以下事项:

  • GO 以外,所有 sqlcmd 命令必须以冒号 (:) 为前缀。

    重要

    为了保持现有 osql 脚本的后向兼容性,有些命令会被视为不带冒号,通过 : 指示。

  • sqlcmd 命令只有出现在一行的开头时,才能够被识别。

  • 所有 sqlcmd 命令都不区分大小写。

  • 每个命令都必须位于单独的行中。 命令后面不能跟随 Transact-SQL 语句或其他命令。

  • 命令将被立即执行。 它们与 Transact-SQL 语句不同,不会放在执行缓冲区中。

编辑命令

[:]ED

启动文本编辑器。 该编辑器可以用来编辑当前的 Transact-SQL 批处理或上次执行的批处理。 若要编辑上次执行的批处理,必须在上一批处理执行完之后立即键入 ED 命令。

文本编辑器由 SQLCMDEDITOR 环境变量定义。 默认编辑器为 Edit。 若要更改编辑器,请设置 SQLCMDEDITOR 环境变量。 例如,要将编辑器设置为 Microsoft 记事本,请在命令提示符处键入:

SET SQLCMDEDITOR=notepad

[:]RESET

清除语句缓存。

:List

输出语句缓存的内容。

变量

:Setvar <var> [ "value" ]

定义 sqlcmd 脚本变量。 脚本变量具有如下格式: $(VARNAME)

变量名称不区分大小写。

可以通过下列方式设置脚本变量:

  • 隐式使用命令行选项。 例如,-l 选项设置 SQLCMDLOGINTIMEOUT sqlcmd 变量。

  • 显式使用 :Setvar 命令。

  • 在运行 sqlcmd 之前定义一个环境变量。

备注

-X 选项可阻止将环境变量传递给 sqlcmd

如果使用 :Setvar 定义的变量和某个环境变量同名,则使用 :Setvar 定义的变量优先。

变量名中不能包含空格字符。

变量名不能与变量表达式(如 $(var))具有相同的形式。

如果脚本变量的字符串值中含有空格,请用引号将该值引起来。 如果未指定脚本变量的值,则将删除该脚本变量。

:Listvar

显示当前设置的脚本变量列表。

注意

只显示由 sqlcmd 设置的脚本变量和使用 :Setvar 命令设置的脚本变量。

输出命令

:Error <filename> | STDERR | STDOUT

将所有错误输出重定向到 filename 指定的文件、stderrstdout:Error 命令可以在脚本中出现多次。 默认情况下,错误输出发送到 stderr

  • filename

    创建并打开一个要接收输出的文件。 若该文件已经存在,则将其截断为零字节。 若该文件不可用(由于权限或其他原因),将不会切换输出,会将输出发送到上次指定的目标或默认目标。

  • STDERR

    将错误输出切换到 stderr 流。 如果已经重定向,流的重定向目标会收到错误输出。

  • STDOUT

    将错误输出切换到 stdout 流。 如果已经重定向,流的重定向目标会收到错误输出。

:Out <filename> | STDERR | STDOUT

创建所有查询结果并将它们重定向到 file name 指定的文件、stderrstdout。 默认情况下,输出将发送到 stdout。 若该文件已经存在,则将其截断为零字节。 :Out 命令可以在脚本中出现多次。

:Perftrace <filename> | STDERR | STDOUT

创建所有性能跟踪信息并将它们重定向到 file name 指定的文件、stderrstdout。 默认情况下,性能跟踪输出将发送到 stdout。 若该文件已经存在,则将其截断为零字节。 :Perftrace 命令可以在脚本中出现多次。

执行控制命令

:On Error [ exit | ignore ]

设置在脚本或批处理执行过程中发生错误时要执行的操作。

使用 exit 选项时,sqlcmd 退出,并显示相应的错误值。

使用 ignore 选项时,sqlcmd 会忽略错误,并继续执行批处理或脚本。 默认情况下,会输出错误消息。

[:]QUIT

导致 sqlcmd 退出。

[:]EXIT [ ( statement ) ]

允许使用 SELECT 语句的结果作为 sqlcmd 的返回值。 如果为数值,最后一个结果行的第一列将转换为 4 字节的整数(长整型)。 MS-DOS、Linux 和 macOS 将低字节传递给父进程或操作系统错误级别。 Windows 2000 及更高版本传递整个 4 字节整数。 语法为 :EXIT(query)

例如:

:EXIT(SELECT @@ROWCOUNT)

也可以包含 :EXIT 参数,使其作为批处理文件的一部分。 例如,在命令提示符处键入:

sqlcmd -Q ":EXIT(SELECT COUNT(*) FROM '%1')"

使用 sqlcmd 实用工具将圆括号 (()) 中的所有内容发送给服务器。 如果系统存储过程选择了一个集合并返回一个值,则仅返回选择的内容。 如果圆括号中没有任何内容,则 :EXIT() 语句会执行批处理中此语句前的所有内容,然后退出,且不返回任何值。

当指定了不正确的查询时,sqlcmd 将退出,且不返回任何值。

下面是 EXIT 格式的列表:

  • :EXIT

    不执行批处理就立即退出,无返回值。

  • :EXIT( )

    执行批处理后退出,不返回值。

  • :EXIT(query)

    执行包括查询的批处理,返回查询的结果后退出。

如果在 sqlcmd 脚本中使用 RAISERROR,并且出现状态 127,则 sqlcmd 会退出,并将消息 ID 返回给客户端。 例如:

RAISERROR(50001, 10, 127)

该错误会导致 sqlcmd 脚本终止并将消息 ID 50001 返回给客户端。

SQL Server 保留了介于 -1-99 之间的返回值;sqlcmd 定义了以下附加返回值:

返回值 说明
-100 选择返回值前遇到错误。
-101 选择返回值时找不到行。
-102 选择返回值时发生转换错误。

GO [count]

GO 在批处理结束和任何缓存 Transact-SQL 语句执行时发出信号。 该批处理将作为单独的批处理执行多次。 不能在单个批处理中多次声明某个变量。

杂项命令

:r <filename>

将来自 filename 指定的文件中的其他 Transact-SQL 语句和 sqlcmd 命令分析到语句缓存中。 系统会相对于 sqlcmd 在其中运行的启动目录读取 filename。

如果文件包含的 Transact-SQL 语句后面没有跟随 GO,则必须在 :r 的后一行中输入 GO

当遇到批处理终止符之后,将读取并执行该文件。 可以发出多个 :r 命令。 该文件可能包含任何 sqlcmd 命令,包括批处理终止符 GO

注意

每遇到一个 :r 命令,交互模式下显示的行计数都会加一。 :r 命令会显示在 list 命令的输出中。

:ServerList

列出在本地配置的服务器和在网络上广播的服务器的名称。

:Connect server_name[\instance_name] [-l timeout] [-U user_name [-P password]]

连接到 SQL Server 的一个实例。 同时关闭当前的连接。

超时选项:

行为
0 永远等待
n>0 等待 n 秒钟

SQLCMDSERVER 脚本变量反映当前的活动连接。

如果未指定 timeout,则其默认值将为 SQLCMDLOGINTIMEOUT 变量的值。

仅当指定了 user_name (作为选项或环境变量)时,才会提示用户输入密码。 如果已设置 SQLCMDUSERSQLCMDPASSWORD 环境变量,则不会提示用户。 如果未提供选项或未提供环境变量,便会使用 Windows 身份验证模式进行登录。 例如,若要使用集成安全性连接到 SQL Server 的一个实例 instance1(如 myserver),则会使用以下命令:

:connect myserver\instance1

若要使用脚本变量连接到 myserver 的默认实例,则会使用以下设置:

:setvar myusername test
:setvar myservername myserver
:connect $(myservername) $(myusername)

[:]!! command

执行操作系统命令。 若要执行操作系统命令,请用两个感叹号 ( !! ) 开始一行,后面输入操作系统命令。 例如:

:!! dir

注意

该命令在运行 sqlcmd 的计算机上执行。

:XML [ ON | OFF ]

有关详细信息,请参阅本文中的 XML 输出格式JSON 输出格式

:Help

列出 sqlcmd 命令以及每个命令的简短说明。

sqlcmd 文件名

可以使用 sqlcmd 选项或 -i 命令指定 :r 输入文件。 可以使用 -o 选项或 :Error:Out:Perftrace 命令指定输出文件。 以下是使用这些文件的一些原则:

  • :Error:Out:Perftrace 应使用不同的 filename 值。 如果使用了相同的 filename ,这些命令的输入可能会混杂在一起。

  • 如果从本地计算机的 sqlcmd 调用远程服务器上的输入文件,并且该文件包含驱动器文件路径(如 :Out c:\OutputFile.txt),将在本地计算机而不是远程服务上创建输出文件。

  • 有效文件路径包括:C:\<filename>\\<Server>\<Share$>\<filename>"C:\Some Folder\<file name>"。 如果路径中包含空格,请使用引号。

  • 每个新的 sqlcmd 会话都将覆盖现有的同名文件。

信息性消息

sqlcmd 打印输出服务器发送的所有信息性消息。 在以下示例中,执行 Transact-SQL 语句后会输出信息性消息。

启动 sqlcmd。 在 sqlcmd 命令提示符下键入以下查询:

USE AdventureWorks2022;
GO

按 ENTER 后,会输出以下信息性消息:

Changed database context to 'AdventureWorks2022'.

Transact-SQL 查询的输出格式

sqlcmd 首先输出列标题,其中包含在选择列表中指定的列名。 列名使用 SQLCMDCOLSEP 字符分隔。 默认情况下,将使用空格。 如果列名短于列宽,则使用空格填充输出,直到下一列。

此行后跟一行分隔行,分隔行是一系列的破折号字符。 以下输出显示了一个示例。

启动 sqlcmd。 在 sqlcmd 命令提示符下键入以下查询:

USE AdventureWorks2022;
SELECT TOP (2) BusinessEntityID, FirstName, LastName
FROM Person.Person;
GO

当你按下 ENTER 后,系统便会返回以下结果集

BusinessEntityID FirstName    LastName
---------------- ------------ ----------
285              Syed         Abbas
293              Catherine    Abel
(2 row(s) affected)

虽然 BusinessEntityID 列宽只有四个字符,但已将其扩展以适应更长的列名。 默认情况下,输出会在 80 个字符处终止。 可通过使用 -w 选项或设置 SQLCMDCOLWIDTH 脚本变量更改此宽度。

XML 输出格式

FOR XML 子句得到的 XML 输出是在连续流中的未格式化的输出。

若要得到 XML 输出,请使用以下命令: :XML ON

注意

sqlcmd 将采用常见的格式返回错误消息。 XML 文本流中的错误消息还将采用 XML 格式输出。 如果使用 :XML ON,则 sqlcmd 不显示信息性消息。

若要关闭 XML 模式,请使用以下命令::XML OFF

发出 :XML OFF 命令之前不应显示 GO 命令,因为 :XML OFF 命令会将 sqlcmd 切换回面向行的输出。

XML(流式)数据和行集数据不能混合。 如果在执行输出 XML 流的 Transact-SQL 语句之前未发出 :XML ON 命令,则输出为乱码。 发出 :XML ON 命令后,将无法执行输出常规行集的 Transact-SQL 语句。

注意

:XML 命令不支持 SET STATISTICS XML 语句。

JSON 输出格式

若要得到 JSON 输出,请使用以下命令: :XML ON。 否则,输出包括的列名和 JSON 文本。 此输出不是有效的 JSON。

若要关闭 XML 模式,请使用以下命令::XML OFF

有关详细信息,请参阅本文中的 XML 输出格式

使用 Microsoft Entra 身份验证

使用 Microsoft Entra 身份验证的示例:

sqlcmd -S Target_DB_or_DW.testsrv.database.windows.net  -G  -l 30

sqlcmd -S Target_DB_or_DW.testsrv.database.windows.net -G -U bob@contoso.com -P MyAzureADPassword -l 30
sqlcmd -S Target_DB_or_DW.testsrv.database.windows.net  -G  -l 30

sqlcmd -S Target_DB_or_DW.testsrv.database.windows.net -G -U bob@contoso.com -P MyAzureADPassword -l 30
sqlcmd -S Target_DB_or_DW.testsrv.database.windows.net  -G  -l 30

sqlcmd -S Target_DB_or_DW.testsrv.database.windows.net -G -U bob@contoso.com -P MyAzureADPassword -l 30

sqlcmd 最佳做法

使用以下方法来帮助实现最高的安全性和效率。

  • 使用集成安全性。

  • 在自动化环境中使用 -X[1]

  • 使用适当的文件系统权限保护输入文件和输出文件。

  • 若要提高性能,请在一个 sqlcmd 会话中执行尽可能多的操作,而不是在一系列会话中来执行这些操作。

  • 将批处理或查询执行的超时值设置为大于你所预期的值。

使用以下方法来帮助实现最高的正确性:

  • 使用 -V16 记录任何严重性级别为 16 的消息。 严重性级别为 16 的消息指示可由用户纠正的常规错误。

  • 退出进程后,请检查退出代码和 DOS ERRORLEVEL 变量。 sqlcmd 正常返回 0,否则它会将 ERRORLEVEL 设置为 -V 配置的。 换句话说,ERRORLEVEL 的值不应与 SQL Server 报告的错误号相同。 错误号是与系统函数 @@ERROR 相对应 SQL Server 特定的值。 ERRORLEVEL 是 sqlcmd 特定的值,用于指示 sqlcmd 终止的原因,并且它的值会通过指定 -b 命令行参数来影响。

将使用 -V16 与检查退出代码和 DOS ERRORLEVEL 相结合,有助于捕获自动化环境(尤其是生产发布之前的质量检验关)中的错误。