專案部署常需按順序執行數十支 .sql 檔(建庫、建表、索引、預存程序、測試資料…)。手動開啟 SSMS 逐一執行不僅繁瑣,還易因順序錯誤導致部署失敗。購買第三方工具成本高、自寫工具門檻高,sqlcmd + :r 命令 是零成本、原生支援的最佳替代方案。
:r(非 :R)C:\Scripts\
├── CREATE_DB.sql -- 主腳本:建庫 + :r 包含其餘四支
├── CREATE_TABLES.sql -- 建立資料表
├── TABLE_INSERTS.sql -- 插入測試資料
├── CREATE_INDEXES.sql -- 建立索引
└── CREATE_PROCEDURES.sql-- 建立預存程序
/* 主腳本:建立 TestDB 並依序包含子腳本 */
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
/* 建立資料表 */
PRINT '正在建立資料表';
GO
USE TestDB;
GO
IF OBJECT_ID('dbo.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('dbo.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
其他子腳本結構雷同,均以 PRINT 記錄進度、USE TestDB 切換內容、GO 分隔批次。
@echo off
REM create_db.bat
sqlcmd -S .\SQLEXPRESS -E -i "C:\Scripts\CREATE_DB.sql" -o "C:\Scripts\DeployLog.txt"
echo 部署完成,請查看 DeployLog.txt
pause
-S:指定執行個體(本機預設實例用 . 或 localhost)。-E:Windows 驗證(或用 -U/-P 指定 SQL 登入)。-i:輸入主腳本路徑。-o:輸出日誌檔,便於事後稽核。雙擊 create_db.bat,控制台顯示各腳本 PRINT 訊息,日誌檔完整記錄過程。SSMS 物件總管重新整理後,可見 TestDB 及所有表、索引、程序、資料均已建立。
| 優點 | 缺點/注意 |
|---|---|
| 零成本、原生支援、無額外安裝 | 子腳本不可含 GO,需調整習慣 |
| 集中控制順序、變數、錯誤處理 | 大型專案腳本相依複雜時維護成本上升 |
| 易整合至 CI/CD、Agent 作業、批次排程 | 錯誤訊息較簡略,需搭配日誌分析 |
建議:腳本數量 < 20、相依單純時用 sqlcmd + :r;超過規模或需並行、回滾、參數化部署時,建議導入 DbUp、Flyway 或自製部署工具。
掌握 sqlcmd 與 :r 命令,能以最輕量方式實現 SQL 腳本的有序、可重複、可自動化部署。下次面對一堆 .sql 檔發愁時,請記得:一支主腳本、一個 .bat、一鍵搞定。