CDC 是 SQL Server 2008 企業版/開發版引入的功能,透過非同步讀取交易記錄,自動捕獲資料表的 INSERT/UPDATE/DELETE 變更,並持久化至系統表,供下游系統(ETL、快取同步、稽核)消費。優於觸發器:低延遲、低衝突、不侵入業務邏輯。
sysadmin 執行 sp_cdc_enable_db。ALTER AUTHORIZATION ON DATABASE::[目標資料庫] TO [sa];USE GPOSDB; -- 目標資料庫
GO
EXEC sys.sp_cdc_enable_db;
GO
-- 驗證
SELECT is_cdc_enabled,
CASE is_cdc_enabled WHEN 1 THEN '已啟用' ELSE '未啟用' END AS 狀態
FROM sys.databases WHERE name = 'GPOSDB';
成功後,資料庫新增 cdc 結構描述、cdc 使用者、cdc_jobs 系統表,Agent 新增兩項作業:
cdc.GPOSDB_capture(捕獲)、cdc.GPOSDB_cleanup(清理)。
USE GPOSDB;
GO
EXEC sys.sp_cdc_enable_table
@source_schema = 'dbo',
@source_name = 'SYSTEMPARA',
@role_name = NULL, -- 不限制存取角色
@capture_instance = DEFAULT; -- 預設捕獲執行個體名稱
GO
-- 驗證
SELECT name, is_tracked_by_cdc,
CASE is_tracked_by_cdc WHEN 1 THEN '已啟用' ELSE '未啟用' END AS 狀態
FROM sys.tables WHERE object_id = OBJECT_ID('dbo.SYSTEMPARA');
啟用後自動產生變更表 cdc.dbo_SYSTEMPARA_CT 及查詢函數 cdc.fn_cdc_get_all_changes_dbo_SYSTEMPARA、cdc.fn_cdc_get_net_changes_dbo_SYSTEMPARA。
-- 1. 插入測試
INSERT INTO dbo.SystemPara (ParaValue, Name, Description) VALUES ('中國', '中國', '中國');
-- 2. 更新測試
UPDATE dbo.SystemPara SET ParaValue = '德國' WHERE Description = '中國';
-- 3. 刪除測試
DELETE FROM dbo.SystemPara WHERE Description = '中國';
SELECT * FROM cdc.dbo_SYSTEMPARA_CT;
關鍵欄位解讀:
__$operation:1=DELETE、2=INSERT、3=UPDATE(舊值)、4=UPDATE(新值) → UPDATE 產生兩筆。__$start_lsn:交易記錄序號 (LSN),可用於排序、增量讀取。-- 取得完整變更歷程
DECLARE @from_lsn BINARY(10) = sys.fn_cdc_get_min_lsn('dbo_SYSTEMPARA');
DECLARE @to_lsn BINARY(10) = sys.fn_cdc_get_max_lsn();
SELECT * FROM cdc.fn_cdc_get_all_changes_dbo_SYSTEMPARA(@from_lsn, @to_lsn, 'all update old');
GO
-- 取得淨變更(同一鍵值最終狀態)
SELECT * FROM cdc.fn_cdc_get_net_changes_dbo_SYSTEMPARA(@from_lsn, @to_lsn, 'all');
GO
DECLARE @begin_lsn BINARY(10) = sys.fn_cdc_map_time_to_lsn('smallest greater than or equal', '2024-01-01 00:00:00');
DECLARE @end_lsn BINARY(10) = sys.fn_cdc_map_time_to_lsn('largest less than or equal', GETDATE());
SELECT __$operation, __$start_lsn, sys.fn_cdc_map_lsn_to_time(__$start_lsn) AS 變更時間, *
FROM cdc.dbo_SYSTEMPARA_CT
WHERE __$start_lsn BETWEEN @begin_lsn AND @end_lsn;
CDC 自動記錄結構異動至 cdc.ddl_history:
ALTER TABLE dbo.SystemPara ALTER COLUMN ParaValue VARCHAR(120);
SELECT * FROM cdc.ddl_history;
-- 查看目前設定
EXEC sys.sp_cdc_help_jobs;
-- 修改保留期為 100 分鐘(示範)
EXEC sys.sp_cdc_change_job @job_type = 'cleanup', @retention = 100;
GO
-- 重啟作業生效
EXEC sys.sp_cdc_stop_job 'cleanup'; EXEC sys.sp_cdc_start_job 'cleanup';
GO
| 類別 | 物件名稱 | 用途 |
|---|---|---|
| 預存程序 | sp_cdc_enable_db / disable_db | 啟用/停用資料庫 CDC |
| sp_cdc_enable_table / disable_table | 啟用/停用資料表捕獲 | |
| sp_cdc_help_change_data_capture | 檢視所有捕獲設定 | |
| sp_cdc_help_jobs | 檢視捕獲/清理作業設定 | |
| sp_cdc_change_job | 修改作業參數(保留期、輪詢間隔) | |
| sp_cdc_add_job / drop_job / start_job / stop_job | 作業生命週期管理 | |
| 函數 | fn_cdc_get_all_changes_<instance> | 取得完整變更(含中間狀態) |
| fn_cdc_get_net_changes_<instance> | 取得淨變更(最終狀態) | |
| fn_cdc_map_time_to_lsn | 時間轉 LSN(支援 largest/smallest 模式) | |
| fn_cdc_map_lsn_to_time | LSN 轉時間 | |
| fn_cdc_get_min_lsn / get_max_lsn | 取得捕獲實例/資料庫 LSN 邊界 | |
| fn_cdc_has_column_changed | 判斷特定欄位是否在變更中 |
retention。ALTER AUTHORIZATION ON DATABASE::[DB] TO [sa]; 可預防 15517 錯誤。CDC 為 SQL Server 提供了原生、低侵入、高可靠的變更捕獲機制,極大簡化 ETL、快取同步、稽核軌跡等場景的開發。掌握「啟用 → 驗證 → 查詢函數 → 維運調整」完整流程,即可在生產環境穩健落地。記住:Agent 必須跑、擁有者要對、保留期要配、函數要用對,CDC 就能成為你資料整合管線的基石。