核心語法
DML 语句
OUTPUT [INTO @TableVar | OutputTable]
[inserted.* | deleted.* | inserted.Col, deleted.Col ...]
[WHERE ...];
三大場景完整示例
1. INSERT → 捕獲新行 (inserted)
CREATE TABLE T4 (Sid INT PRIMARY KEY, SName VARCHAR(10));
INSERT INTO T4
OUTPUT INSERTED.Sid, INSERTED.SName
SELECT Sid, SName FROM T3; -- 假設 T3 有源數據
-- 結果:返回所有新插入行的 Sid, SName
2. UPDATE → 同步捕獲舊/新值 (deleted / inserted)
UPDATE T4
SET SName = 'snow'
OUTPUT DELETED.SName AS OldName, INSERTED.SName AS NewName
WHERE Sid = 101;
-- 結果:OldName='wind', NewName='snow'
3. DELETE → 捕獲被刪除行 (deleted)
DELETE T4
OUTPUT DELETED.Sid, DELETED.SName
WHERE Sid = 103;
-- 結果:返回被刪除行的 Sid, SName
進階用法
| 場景 | 寫法 | 說明 |
| 輸出到表變量/臨時表 | `OUTPUT INSERTED.* INTO @Changes` | 後續批次處理、審計日志 |
| MERGE 陳述式 | `OUTPUT $action, INSERTED.*, DELETED.*` | `$action` 返回 'INSERT'/'UPDATE'/'DELETE' |
| 觸發器替代 | 簡單審計場景用 OUTPUT 替代 AFTER 觸發器 | 性能更好、邏輯集中 |
| 捕獲計算列/默認值 | `OUTPUT INSERTED.ComputedCol` | 自動獲取生成值 |
關鍵限制
- 不支援 `OUTPUT INTO` 目標表有觸發器 / 參與復制 / 有外鍵約束 (部分版本)
- `INSERTED`/`DELETED` 中不可引用 `TEXT/NTEXT/IMAGE` (已棄用類型),`VARCHAR(MAX)`/`VARBINARY(MAX)` 支援
- 不可在 `OUTPUT` 中使用子查詢/聚合
實戰模式:異步審計日志
DECLARE @Audit TABLE (Op CHAR(1), TableName SYSNAME, PKVal INT, OldData NVARCHAR(MAX), NewData NVARCHAR(MAX), ModTime DATETIME2 DEFAULT SYSUTCDATETIME());
UPDATE CoreTable
SET Col1 = @NewVal
OUTPUT 'U', 'CoreTable', INSERTED.PK,
(SELECT * FROM DELETED FOR JSON AUTO),
(SELECT * FROM INSERTED FOR JSON AUTO)
INTO @Audit
WHERE PK = @ID;
-- 批次寫入審計表
INSERT INTO AuditLog SELECT * FROM @Audit;