SQL Server 2005 引入 OUTPUT 子句,可在 DML 陳述式中直接返回插入、刪除、更新前後的資料,無需觸發器或額外查詢,極大簡化業務邏輯與審計實作。
IF OBJECT_ID('dbo.TestTB') IS NOT NULL DROP TABLE dbo.TestTB;
CREATE TABLE dbo.TestTB (
ID INT IDENTITY(1,1) PRIMARY KEY,
Province VARCHAR(50),
City VARCHAR(50)
);
INSERT INTO dbo.TestTB (Province, City)
OUTPUT INSERTED.Province, INSERTED.City, INSERTED.ID -- 可指定欄位或 INSERTED.*
VALUES ('廣東', '深圳');
-- 結果: 省份=廣東, 城市=深圳, ID=1
DELETE FROM dbo.TestTB
OUTPUT DELETED.*
WHERE ID = 1;
-- 結果: 完整被刪除列
UPDATE dbo.TestTB
SET Province = '湖南', City = '郴州'
OUTPUT '更新前:' + DELETED.Province + DELETED.City AS BeforeData,
'更新後:' + INSERTED.Province + INSERTED.City AS AfterData
WHERE ID = 1;
-- 結果: BeforeData=更新前:廣東深圳, AfterData=更新後:湖南郴州
DECLARE @AuditLog TABLE (
ID INT, Province VARCHAR(50), City VARCHAR(50),
ActionType VARCHAR(10), ChangeTime DATETIME DEFAULT GETDATE()
);
-- 刪除並記錄
DELETE FROM dbo.TestTB
OUTPUT DELETED.ID, DELETED.Province, DELETED.City, 'DELETE' INTO @AuditLog
WHERE ID > 4;
SELECT * FROM @AuditLog;
| 模式 | 用途 | 範例 |
|---|---|---|
| OUTPUT INTO 歷史表 | 刪除/更新前自動備份 | DELETE ... OUTPUT DELETED.* INTO HistoryTable ... |
| OUTPUT $action (MERGE) | 識別 MERGE 動作類型 | MERGE ... OUTPUT $action, INSERTED.*, DELETED.* INTO @Log ... |
| OUTPUT 搭配 TRY/CATCH | 異常時仍可取得部分結果 | 在 CATCH 區塊處理 @Log 表變數 |
| OUTPUT 計算欄位 | 直接返回衍生值 | OUTPUT INSERTED.Qty * INSERTED.Price AS Amount |
FILESTREAM、text/ntext/image 欄位時有限制。TOP 子句的不確定順序 (需加 ORDER BY 於子查詢)。善用 OUTPUT 子句,可將「異動執行」與「結果取得/審計記錄」合為原子操作,提升效能並簡化代碼,是 SQL Server 開發必備技能。