SQL Server 按顺序执行多个 SQL 脚本的自动化方法

Ada
Ada
发布时间:2026-10-14 | 4人浏览过
原创

在 SQL Server 开发与管理中,往往需要将数据库创建、建表、插入数据等操作拆分为多个独立的 SQL 文件。虽然 SSMS 支持多窗口执行,但缺乏顺序控制。本文将演示如何使用 sqlcmd 命令行工具的 :r 命令,将多个脚本文件嵌套引用,并通过批处理文件实现一键自动化部署。

核心原理:SQLCMD 与 :r 命令

sqlcmd 是微软提供的命令行实用程序,允许用户在命令提示符或脚本中输入 Transact-SQL 语句。其核心优势在于能够作为操作系统的一部分执行 T-SQL。

要实现脚本的顺序执行,关键在于 :r 命令(注意大小写敏感):
- 当 sqlcmd 解析到 :r filename 时,它会立即读取指定的文件内容,并将其视为当前脚本的一部分。
- 这种方法允许定义全局变量集,无需在每个子脚本中重复声明,且能严格保持代码执行的逻辑顺序。

操作步骤:构建批量执行环境

第1步:准备脚本目录与文件

目的:整理散乱的 SQL 文件,确立以“主脚本”为入口的执行结构。
操作:在磁盘根目录或项目目录下创建文件夹,例如 C:\Scripts。在此文件夹中放置所有相关的 SQL 脚本文件。

第2步:编写主调用脚本 (Master Script)

目的:作为执行入口,负责任务调度和状态输出。
参数:各子脚本的物理路径。
动作:

-- 文件名: CREATE_DB.sql (主脚本)
SET NOCOUNT ON
GO

PRINT '开始创建TestDB数据库'
-- 若库存在则删除,确保环境干净
IF EXISTS (SELECT 1 FROM SYS.DATABASES WHERE NAME = 'TestDB')
DROP DATABASE TestDB
GO
CREATE DATABASE TestDB
GO

-- 错误处理:遇到致命错误停止后续执行
:On Error exit

-- 关键步骤:按顺序嵌入其他脚本
:r c:\Scripts\CREATE_TABLES.sql
:r c:\Scripts\TABLE_INSERTS.sql
:r c:\Scripts\CREATE_INDEXES.sql
:r c:\Scripts\CREATE_PROCEDURES.sql

PRINT '创建完毕'
GO

第3步:编写被调用的子脚本

目的:完成具体的对象创建任务。
注意:子脚本中尽量避免再次使用 :r 导致层级过深,建议保持扁平化结构。

表结构创建脚本 (CREATE_TABLES.sql):

/* 创建数据表 */
PRINT '正在创建数据表 '
GO
USE TestDB
GO

-- 员工表
IF OBJECT_ID('EMPLOYEE') IS NOT NULL DROP TABLE DBO.EMPLOYEE
GO
CREATE TABLE DBO.EMPLOYEE
(
  EMPLOYEEID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
  FIRSTNAME VARCHAR(50),
  LASTNAME VARCHAR(50)
)
GO

-- 考勤表
IF OBJECT_ID('TIMECARD') IS NOT NULL DROP TABLE DBO.TIMECARD
GO
CREATE TABLE DBO.TIMECARD
(
  TIMECARDID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
  EMPLOYEEID INT NOT NULL,
  HOURSWORKED TINYINT NOT NULL,
  HOURLYRATE MONEY NOT NULL,
  DATEWORKED DATETIME NOT NULL
)
GO

数据插入脚本 (TABLE_INSERTS.sql):

/* 插入表数据 */
PRINT '正在插入数据到表 EMPLOYEE'
GO
USE TestDB
GO

INSERT INTO DBO.EMPLOYEE (FIRSTNAME, LASTNAME) SELECT 'JOHN', 'DOE' UNION ALL SELECT 'JANE', 'DOE' UNION ALL SELECT 'JEFF', 'DOE'
GO

索引创建脚本 (CREATE_INDEXES.sql):

/* 创建索引 */
PRINT '开始创建索引'
GO
USE TestDB
GO

IF NOT EXISTS (
    SELECT 1 FROM SYS.INDEXES 
    WHERE NAME = 'IX_EMPLOYEE_LASTNAME'
) 
CREATE INDEX IX_EMPLOYEE_LASTNAME ON DBO.EMPLOYEE(LASTNAME, FIRSTNAME)
GO

存储过程脚本 (CREATE_PROCEDURES.sql):

/* 创建存储过程 */
PRINT '正在创建存储过程'
GO
USE TestDB
GO

IF OBJECT_ID('GET_EMPLOYEE_TIMECARDS') IS NOT NULL 
  DROP PROCEDURE DBO.GET_EMPLOYEE_TIMECARDS
GO

CREATE PROCEDURE DBO.GET_EMPLOYEE_TIMECARDS @EMPLOYEEID INT
AS 
BEGIN
  SET NOCOUNT ON
  SELECT * 
  FROM DBO.EMPLOYEE E
  JOIN DBO.TIMECARD T ON E.EMPLOYEEID = T.EMPLOYEEID
  WHERE E.EMPLOYEEID = @EMPLOYEEID
  ORDER BY DATEWORKED
END
GO

第4步:创建 Windows 批处理文件 (.bat)

目的:提供用户友好的双击执行入口,封装复杂的命令行参数。
路径示例:C:\create_db.bat
内容如下:

@echo off
echo Starting Database Setup...
sqlcmd -S localhost -U sa -P YourPassword -i "C:\Scripts\CREATE_DB.sql"
pause

参数说明:
- -S:指定服务器实例名称。
- -U / -P:指定登录名和密码(生产环境中建议使用集成验证或环境变量)。

执行结果观察

直接点击生成的 create_db.bat 文件即可触发整个流程。以下是执行过程中的典型界面反馈:

执行前,目标数据库中不存在相关对象:

控制台会显示 sqlcmd 的运行日志及 PRINT 语句的输出信息,表明脚本正在逐行处理:

执行完成后,SSMS 刷新查看结果。可以看到数据库、表、数据、索引及存储过程已完整创建:

简要总结

对于少量且关联紧密的 SQL 脚本,使用 :r 命令是最轻量级的方案。它避免了第三方依赖,同时提供了比纯文本拼接更严谨的控制流(如错误退出机制)。若脚本数量庞大,建议进一步封装为 PowerShell 脚本或使用专门的 CI/CD 部署工具。以上就是使用 SQLCMD 批量执行 SQL Server 脚本的详细内容,更多关于 SQL Server 数据库维护的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表