使用 sqlcmd

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

sqlcmd 是一个命令行实用程序,用于 Transact-SQL (T-SQL) 语句和脚本的临时、交互执行以及自动执行 T-SQL 脚本撰写任务。 若要以交互方式使用 sqlcmd,或要生成用于 sqlcmd 的脚本文件,则须了解 T-SQL。 有多种方式可以使用 sqlcmd。 例如:

  • 通过命令提示符输入 T-SQL 语句。 控制台会返回结果。 若要打开命令提示符窗口,请在 Windows 搜索框中输入 cmd,然后选择“命令提示符”将其打开。 在命令提示符处,键入 sqlcmd,后面跟随所需的选项列表。 有关 sqlcmd 支持的选项的完整列表,请参阅 sqlcmd 实用工具

  • 通过下列方式提交 sqlcmd 作业:指定要执行的单个 T-SQL 语句,或将实用工具指向要执行的 T-SQL 语句所在的文本文件。 输出定向到一个文本文件,但也可能在命令提示符处显示。

  • SQL Server Management Studio (SSMS) 查询编辑器中的 SQLCMD 模式

  • SQL Server 管理对象 (SMO)。

  • SQL Server 代理 CmdExec 作业。

sqlcmd 常用选项

  • 服务器选项 (-S),用于标识 sqlcmd 连接到的 SQL Server 实例。

  • 身份验证选项(-E-U-P),用于指定 sqlcmd 连接到 SQL Server 实例所使用的凭据。

    注意

    -E 选项为默认选项,无需指定。

  • 输入选项(-Q-q-i),用于标识 sqlcmd 输入的位置 sqlcmd

  • 输出选项 (-o),用于指定 sqlcmd 输出所在的文件。

连接到 sqlcmd 实用工具

  • 使用 Windows 身份验证连接到默认实例,以交互方式运行 T-SQL 语句:

    sqlcmd -S <ComputerName>
    

    注意

    上述示例中,未指定 -E,因为它是默认选项,而且 sqlcmd 使用 Windows 身份验证连接到默认实例。

  • 使用 Windows 身份验证连接到命名实例,以交互方式运行 T-SQL 语句:

    sqlcmd -S <ComputerName>\<InstanceName>
    

    sqlcmd -S .\<InstanceName>
    
  • 使用 Windows 身份验证连接到命名实例,并指定输入和输出文件:

    sqlcmd -S <ComputerName>\<InstanceName> -i <MyScript.sql> -o <MyOutput.rpt>
    
  • 使用 Windows 身份验证连接到本地计算机上的默认实例,执行查询,并在查询完成后让 sqlcmd 保持运行状态:

    sqlcmd -q "SELECT * FROM AdventureWorks2022.Person.Person"
    
  • 使用 Windows 身份验证连接到本地计算机上的默认实例,执行查询,将输出定向到某个文件,并在查询完成后退出 sqlcmd:

    sqlcmd -Q "SELECT * FROM AdventureWorks2022.Person.Person" -o MyOutput.txt
    
  • 使用 SQL Server 身份验证连接到命名实例,以交互方式运行 T-SQL 语句,并由 sqlcmd 提示输入密码:

    sqlcmd -U MyLogin -S <ComputerName>\<InstanceName>
    

    提示

    若要查看 sqlcmd 实用工具所支持选项的列表,请运行: sqlcmd -?

使用 sqlcmd 以交互方式运行 Transact-SQL 语句

你可以使用 sqlcmd 实用工具以交互方式在命令提示符窗口中执行 T-SQL 语句。 若要使用 sqlcmd 以交互方式执行 Transact-SQL 语句,请在未使用 -Q-q-Z-i 选项指定任何输入文件或查询的情况下运行该实用工具。 例如:

sqlcmd -S <ComputerName>\<InstanceName>

在未指定输入文件或查询的情况下执行命令时,sqlcmd 连接到 SQL Server 的指定实例,然后显示一个新行,其中包含 1> 并且后跟一个闪烁的下划线(称为 sqlcmd 提示符)。 1 表示这是 T-SQL 语句的第一行,而 sqlcmd 提示符则是你键入 T-SQL 语句的起点。

sqlcmd 提示符中,可以键入 T-SQL 语句和 sqlcmd 命令,如 GOEXIT。 每个 T-SQL 语句放置在称为“语句缓存”的缓冲区中。 键入 GO 命令并按 Enter 键后,这些语句将发送到 SQL Server。 若要退出 sqlcmd,请在新行的开头键入 EXITQUIT

若要清除语句缓存,请键入 :RESET。 键入 Ctrl+C 可使 sqlcmd 退出。 在发出 Ctrl+C 命令后,还可以用 GO 停止语句缓存的执行。

通过输入 :ED 命令和 sqlcmd 提示符,可以编辑交互式会话中输入的 Transact-SQL 语句。 编辑器将打开,编辑 T-SQL 语句并关闭编辑器后,修改后的 T-SQL 语句将显示在命令窗口中。 输入 GO 以运行修改后的 T-SQL 语句。

带引号的字符串

用引号引起来的字符无需任何额外的预处理即可使用。例外,输入两个连续的引号可以将引号插入字符串中。 SQL Server 将这种字符序列视作一个引号。 (但在服务器上会进行转换。)当脚本变量出现在字符串中时,不会展开它们。

例如:

sqlcmd
PRINT "Length: 5"" 7'";
GO

结果集如下。

Length: 5" 7'

跨多行的字符串

sqlcmd 支持跨多行的字符串。 例如,下面的 SELECT 语句跨多行,但键入 GO 并按 Enter 键后,即会作为单个字符串执行。

SELECT <First line>
FROM <Second line>
WHERE <Third line>;
GO

交互式 sqlcmd 示例

本示例说明了以交互方式运行 sqlcmd 的过程。

打开命令提示符窗口时,出现如下一行内容:

C:\Temp\>

这表示文件夹 C:\Temp\ 为当前文件夹,如果你指定文件名,则 Windows 将在此文件夹中查找这个文件。

键入 sqlcmd 以连接到本地计算机上的 SQL Server 默认实例,命令提示符窗口内容将显示为:

C:\Temp>sqlcmd
1>

这表示你已连接到 SQL Server 实例,并且 sqlcmd 现在已可以接受 T-SQL 语句和 sqlcmd 命令。 1> 后闪烁的下划线是 sqlcmd 提示符,它标明了所键入语句和命令的显示位置。 现在,键入 USE AdventureWorks2022 并按 Enter 键,然后键入 GO 并按 ENTER 键。 命令提示符窗口的内容如下:

sqlcmd
USE AdventureWorks2022;
GO

结果集如下。

Changed database context to 'AdventureWorks2022'.
1>

按下 Enter 时,它会向 sqlcmd 发出信号,启动新行。 键入 GO 后按 Enter 键,即向 sqlcmd 发出信号将 USE AdventureWorks2022 语句发送到 SQL Server 实例。 sqlcmd 随后返回一条消息,指示 USE 语句已成功完成并显示新的 1> 提示符作为输入新语句或命令的信号。

下面的示例说明了键入 SELECT 语句和 GO 执行 SELECT以及键入 EXIT 退出 sqlcmd 时命令提示符窗口包含的内容:

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

结果集如下。

BusinessEntityID  FirstName  LastName
----------------- ---------- ------------
1                 Syed       Abbas
2                 Catherine  Abel
3                 Kim        Abercrombie

生成输出后,sqlcmd 重置 sqlcmd 提示符并显示 1>。 若要结束会话,请在 1> 提示符中键入 EXIT。 现在可以再键入一个 EXIT 命令关闭命令提示符窗口。

创建并查询 SQL Server 容器

你可以使用 sqlcmd (Go),在容器中创建 SQL Server 的新实例。 sqlcmd (Go) 暴露 create 语句,该语句允许指定容器映像和 SQL Server 备份,以便快速创建用于开发、调试和分析的 SQL Server 实例。

重要

需要安装容器运行时,例如 Docker,或者 Podman

以下命令显示如何查看所有可用选项,以创建新的 SQL Server 容器:

sqlcmd create mssql --help

以下命令通过使用最新版本的 SQL Server 2022 (16.x) 创建新的 SQL Server 实例,然后还原 Wide World Importers 示例数据库:

sqlcmd create mssql --accept-eula --tag 2022-latest --using https://github.com/Microsoft/sql-server-samples/releases/download/wide-world-importers-v1.0/WideWorldImporters-Full.bak

创建 SQL Server 实例后,可以使用 sqlcmd (Go) 来进行管理和查询。

以下命令可确认已创建的实例的版本:

sqlcmd query "SELECT @@version"

以下命令可使用已创建的实例启动交互式会话:

sqlcmd query

以下命令可打开 Azure Data Studio,并自动连接到在创建过程中已还原的数据库:

sqlcmd open ads

以下命令可列出用于连接到已创建的实例的连接字符串:

sqlcmd config connection-strings

以下命令用于在不再需要容器时将其移除:

sqlcmd delete

使用 sqlcmd 运行 Transact-SQL 脚本文件

可以使用 sqlcmd 执行数据库脚本文件。 脚本文件是一些文本文件,它们同时包含 T-SQL 语句、sqlcmd 命令和脚本变量。 有关如何使用脚本变量的详细信息,请参阅 将 sqlcmd 与脚本变量结合使用sqlcmd 与脚本文件中语句、命令和脚本变量的配合方式类似于它与交互输入的语句和命令的配合方式。 主要区别在于 sqlcmd 从输入文件连续读取内容,而不是等待用户输入语句、命令和脚本变量。

可以通过几种不同的方式创建数据库脚本文件:

  • 可以在 SQL Server Management Studio 中以交互方式生成和调试一组 T-SQL 语句,然后将“查询”窗口中的内容另存为脚本文件。

  • 可以使用记事本等文本编辑器创建包含 T-SQL 语句的文本文件。

示例

A. 使用 sqlcmd 运行脚本

启动记事本并键入以下 T-SQL 语句:

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

创建一个名为 MyFolder 的文件夹,然后将脚本另存为文件夹 MyScript.sql 中的文件 C:\MyFolder。 在命令提示符处输入以下命令运行脚本,并将输出放入 MyOutput.txtMyFolder中:

sqlcmd -i C:\MyFolder\MyScript.sql -o C:\MyFolder\MyOutput.txt

结果集如下。

Changed database context to 'AdventureWorks2022'.
BusinessEntityID  FirstName  LastName
----------------- ---------- ------------
1                 Syed       Abbas
2                 Catherine  Abel
3                 Kim        Abercrombie
(3 rows affected)

B. 通过专用管理连接使用 sqlcmd

在下面的示例中,sqlcmd 通过专用管理员连接 (DAC) 连接到一台具有阻塞问题的服务器。

C:\Temp\>sqlcmd -S ServerName -A
1> SELECT session_id, blocking_session_id FROM `sys.dm_exec_requests` WHERE blocking_session_id <> 0;
2> GO

结果集如下。

session_id   blocking_session_id
-----------  --------------------`
62           64
(1 rows affected)

使用 sqlcmd 结束阻塞进程。

1> KILL 64;
2> GO

°C 使用 sqlcmd 执行存储过程

下面的示例说明如何使用 sqlcmd 执行存储过程。 创建以下存储过程。

USE AdventureWorks2022;
GO

IF OBJECT_ID('dbo.ContactEmailAddress', 'P') IS NOT NULL
    DROP PROCEDURE dbo.ContactEmailAddress;
GO

CREATE PROCEDURE dbo.ContactEmailAddress (
    @FirstName NVARCHAR(50),
    @LastName NVARCHAR(50)
)
AS
SET NOCOUNT ON;

SELECT EmailAddress
FROM Person.Person
WHERE FirstName = @FirstName
    AND LastName = @LastName;

SET NOCOUNT OFF;
GO

sqlcmd 提示符下,输入以下内容:

C:\Temp\sqlcmd
1> :Setvar FirstName Gustavo
1> :Setvar LastName Achong
1> EXEC dbo.ContactEmailAddress $(FirstName),$(LastName)
2> GO
EmailAddress
-----------------------------
gustavo0@adventure-works.com

D. 使用 sqlcmd 进行数据库维护

下面的示例说明了如何将 sqlcmd 用于数据库维护任务。 使用以下代码创建 C:\Temp\BackupTemplate.sql

USE master;
BACKUP DATABASE [$(db)] TO DISK='$(bakfile)';

sqlcmd 提示符下,输入以下代码:

C:\Temp\>sqlcmd
1> :connect <server>
Sqlcmd: Successfully connected to server <server>.
1> :setvar db msdb
1> :setvar bakfile C:\Temp\msdb.bak
1> :r C:\Temp\BackupTemplate.sql
2> GO
Changed database context to 'master'.
Processed 688 pages for database 'msdb', file 'MSDBData' on file 2.
Processed 5 pages for database 'msdb', file 'MSDBLog' on file 2.
BACKUP DATABASE successfully processed 693 pages in 0.725 seconds (7.830 MB/sec)

E. 使用 sqlcmd 对多个实例执行代码

某文件中的以下代码表示一个连接到两个实例的脚本。 请注意连接到第二个实例之前的 GO

:CONNECT <server>\,<instance1>
EXEC dbo.SomeProcedure
GO
:CONNECT <server>\,<instance2>
EXEC dbo.SomeProcedure
GO

E. 返回 XML 输出

下面的示例说明了如何以连续流返回未格式化的 XML 输出。

C:\Temp\>sqlcmd -d AdventureWorks2022
1> :XML ON
1> SELECT TOP 3 FirstName + ' ' + LastName + ', '
2> FROM Person.Person
3> GO
Syed Abbas, Catherine Abel, Kim Abercrombie,

F. 在 Windows 脚本文件中使用 sqlcmd

在 .bat 文件中,sqlcmd 命令(如 sqlcmd -i C:\Temp\InputFile.txt -o C:\Temp\OutputFile.txt, )可以与 VBScript 一起执行。 此时,不要使用交互选项。 执行 .bat 文件的计算机上必须安装 sqlcmd。

首先,在 C:\Temp 中创建以下四个文件:

  • C:\Temp\badscript.sql

    SELECT batch_1_this_is_an_error
    GO
    SELECT 'batch #2'
    GO
    
  • C:\Temp\goodscript.sql

    SELECT 'batch #1';
    GO
    SELECT 'batch #2';
    GO
    
  • C:\Temp\returnvalue.sql

    :exit(select 100)
    
  • C:\Temp\windowsscript.bat

    @echo off
    
    echo Running badscript.sql
    sqlcmd -i badscript.sql -b -o out.log
    if not errorlevel 1 goto next1
    echo == An error occurred
    
    :next1
    
    echo Running goodscript.sql
    sqlcmd -i goodscript.sql -b -o out.log
    if not errorlevel 1 goto next2
    echo == An error occurred
    
    :next2
    echo Running returnvalue.sql
    sqlcmd -i returnvalue.sql -o out.log
    echo SQLCMD returned %errorlevel% to the command shell
    
    :exit
    

然后,在命令提示符处运行 C:\Temp\windowsscript.bat

C:\Temp\>windowsscript.bat
Running badscript.sql
== An error occurred
Running goodscript.sql
Running returnvalue.sql

SQLCMD returned 100 to the command shell

G. 使用 sqlcmd 在 Azure SQL 数据库上设置加密

可对与 SQL 数据库数据的连接执行 sqlcmd 以指定加密和证书信任。 有两个 sqlcmd 选项可供选择:

  • -N 开关,客户端使用它来请求加密连接。 此选项等同于 ADO.net 选项 ENCRYPT = true

  • -C 开关,客户端用来将其配置为隐式信任服务器证书且不对其进行验证。 此选项等同于 ADO.net 选项 TRUSTSERVERCERTIFICATE = true

SQL 数据库服务并不支持 SQL Server 实例上所有可用的 SET 选项。 当将相应的 SET 选项设置为 ONOFF时,下面的选项将引发错误:

  • SET ANSI_DEFAULTS
  • SET ANSI_NULLS
  • SET REMOTE_PROC_TRANSACTIONS
  • SET ANSI_NULL_DEFAULT

下面的 SET 选项虽然不会引发异常,但无法使用。 已将它们弃用:

  • SET CONCAT_NULL_YIELDS_NULL
  • SET ANSI_PADDING
  • SET QUERY_GOVERNOR_COST_LIMIT

语法

以下示例介绍了 SQL Server Native Client 访问接口设置包括的情况:

  • ForceProtocolEncryption = False
  • Trust Server Certificate = No

使用 Windows 凭据进行连接并对通信加密:

sqlcmd -E -N

使用 Windows 凭据进行连接并信任服务器证书:

sqlcmd -E -C

使用 Windows 凭据进行连接、对通信加密并信任服务器证书:

sqlcmd -E -N -C

以下示例介绍了 SQL Server Native Client 访问接口设置包括的情况:

  • ForceProtocolEncryption = True
  • TrustServerCertificate = Yes

使用 Windows 凭据进行连接、对通信加密并信任服务器证书:

sqlcmd -E

使用 Windows 凭据进行连接、对通信加密并信任服务器证书:

sqlcmd -E -N

使用 Windows 凭据进行连接、对通信加密并信任服务器证书:

sqlcmd -E -C

使用 Windows 凭据进行连接、对通信加密并信任服务器证书:

sqlcmd -E -N -C

如果访问接口指定了 ForceProtocolEncryption = True,则启用加密,即使连接字符串中具有 Encrypt=No