需將 SQL 查詢結果定時導出為 CSV/文本文件,供下游系統消費。直接在應用層查詢再寫入文件效率低、耦合重;利用 SQL Server 原生 bcp 工具配合 xp_cmdshell,可在資料庫層完成「查詢 → 導出」閉環。
| 參數 | 用途 | 常用值 |
|---|---|---|
queryout | 導出查詢結果 | 固定 |
-c | 字元模式(預設 tab 分隔) | 通用文本 |
-w | Unicode 寬字元模式 | 含中文時推薦 |
-t | 欄位分隔符 | -t , 產生 CSV |
-r | 列分隔符 | -r \n |
-S | 目標實例 | -S localhost |
-U / -P | 帳號/密碼 | 或用 -T 信任連線 |
-k | 保留 NULL 為空字串 | 避免輸出 NULL 字面值 |
sp_sql_query_to_fileCREATE PROCEDURE dbo.sp_sql_query_to_file
@servername VARCHAR(50), -- 實例名
@username VARCHAR(50), -- 空字串表信任連線
@password VARCHAR(50),
@sql_query VARCHAR(2000), -- 查詢語句,單引號需雙寫
@filePath_name VARCHAR(1000),-- 輸出路徑(不含副檔名)
@date DATETIME -- 日期戳
AS
BEGIN
SET NOCOUNT ON;
DECLARE @cmd VARCHAR(8000);
SET @cmd = 'bcp "' + @sql_query + '" queryout "'
+ @filePath_name + '_' + CONVERT(VARCHAR(12), @date, 112) + '.txt"'
+ ' -t "," -w' -- CSV + Unicode
+ ' -S ' + @servername
+ CASE WHEN ISNULL(@username,'') = '' THEN '' ELSE ' -U ' + @username END
+ ' -P ' + ISNULL(@password,'');
EXEC master..xp_cmdshell @cmd;
IF @@ERROR <> 0
PRINT '導出失敗,請檢查錯誤碼:' + CAST(@@ERROR AS VARCHAR);
END;
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
EXECUTE 權限,不開放直接呼叫 xp_cmdshell。EXEC dbo.sp_sql_query_to_file
@servername = 'localhost',
@username = '',
@password = '',
@sql_query = 'SELECT id, name, created_at FROM dbo.orders WHERE status = ''Completed''',
@filePath_name = 'D:\Export\orders_completed',
@date = GETDATE();
生成文件:orders_completed_20240518.txt,UTF-16 LE 編碼,欄位以逗號分隔。
| 現象 | 原因 | 解決 |
|---|---|---|
| 「存取被拒」 | 服務帳號無目錄寫入權限 | 授予目錄 Modify 權限或更換輸出路徑 |
| 中文亂碼 | 未使用 -w 或編碼不匹配 | 加 -w(Unicode)或 -C 65001(UTF-8) |
| 大數據導出慢 | 單執行緒、網路瓶頸 | 分批導出、壓縮傳輸、或改用 SSIS / PolyBase |
若需輕量、純 T-SQL、無額外元件依賴,bcp + xp_cmdshell 仍是最快落地的選擇。