SQL Server 2008 CDC筆記

    change data capture是在每次對數據庫執行insert、update、delete操作的時候,捕獲變更數據的方法,這在數據倉庫中是常用到的技術手段。Oracle早在9i中就加入了這一特性,在多年後的今天,SQL Server總算是提供了同樣的功能。

     相關存儲過程

1、開啓數據庫的CDC功能:sp_cdc_enable_db

執行sp_cdc_enable_db後會自動cdc架構並創建幾個CDC相關的系統表

cdc.captured_columns:存放所有被捕捉的列

cdc.change_tables:返回啓用CDC的表.使用sys.sp_cdc_help_change_data_capture比直接查詢好.

cdc.ddl_history:返回每個表再啓用CDC後的DDL變更.可以使用sys.sp_cdc_get_ddl_history代替查詢該表.

cdc.index_columns:返回啓用CDC的表的相關索引列.同樣用sys.sp_cdc_help_change_data_capure來獲取比較好.

cdc.lsn_time_mapping:爲每個在更改表中存在行的事務返回一行.該表用於在日誌序列號(LSN) 提交值和提交事務的時間之間建立映射,要避免直接查詢該表,使用sys.fn_cdc_map_lsn_to_time和sys.fn_cdc_map_time_to_lsn函數.

 

2、開啓數據表的CDC功能:sp_cdc_enable_table

參數:@source_schema:源架構(systemname)

@source_name:源表的名稱(systemname)

@capture_instance:捕捉實例名稱,可爲null,當設爲null是,自動命名爲 “架構名_表名_CT” (systemname)

@supports_net_changes :是否使用淨變化數據,如果是的話,源表必須有主鍵或者指定唯一標識列(bit)

@role_name:獲取變化數據的數據庫角色,如果角色不存在,sp_cdc_enable_table_change_data_capture過程執行成功後會創建角色,必須指定一個名稱(systemname)

@indexname:唯一索引名,可爲空(systemname)

@captured_column_list:捕捉列,如果爲null則捕捉表中所有列(nvarchar(max))

@filegroup_name:變更數據表使用的文件組,可爲空(systemname)

執行sp_cdc_enable_db 後會自動創建一個cdc架構下的系統表和兩個函數

 

cdc.架構名_表名:這個系統表記錄該示例所有更改的數據

其中有幾個特殊的列:

__$start_lsn:與相應更改的提交事務關聯的日誌序列號(LSN).

__$end_lsn:

__$seqval:用於對事務內的行更改進行排序的序列值.

__$operation:識與相應更改關聯的數據操作語言(DML) 操作.可以是下列值之一:1 = 刪除;2 = 插入;3 = 更新(舊值)列數據中具有執行更新語句之前的行值.4 = 更新(新值)列數據中具有執行更新語句之後的行值.

__$update_mask:基於更改表的列序號的位掩碼,用於標識那些發生更改的列。

其餘是被跟蹤的列

 

cdc.fn_cdc_get_all_changes_架構名_表名:這個函數能夠返回更改的數據

cdc.fn_cdc_get_net_changes_架構名_表名:這個函數能夠返回淨變化的數據

 

例如:execute sys.sp_cdc_enable_table 'dbo','recordoriginaldata',1,'caputuretest',1,'capturerole',null,null,null,null

 

3、關閉數據庫CDC功能:sp_cdc_disable_db

4、關閉數據表CDC功能:sp_cdc_disable_table

參數:@source_schema:源架構(systemname)

@sourece_name:源表名稱(systemname)

@capture_instance:捕捉示例名稱(systemname)

 

5、查詢數據捕捉的配置:sys.sp_cdc_help_change_data_capture

參數:@source_schema:

@source_name:

 

    相關函數

1、sys.fn_cdc_map_time_to_lsn:根據日誌序列號返回執行此條事務的時間

參數:@lsn:事務日誌的序列號

 

2、sys.fn_cdc_map_time_to_lsn:獲取變更範圍內的的最大或最小LSN值,這函數有個 輸入值關係運算符和跟蹤時間.關係運算符有:smallest greater than;  smallest greater than or equal;    largest less than;largest less than or equal.

參數:@relation_operator:以上四個關係運算符之一

@tracking_time:跟蹤時間

 

3、獲取更改的數據:cdc.fn_cdc_get_all_changes_架構名_表名

4、獲取淨變化的數據:cdc.fn_cdc_get_net_changes_架構名_表名

參數:@from_lsn:開始日誌序列號(binary)

@to_lsn:結束日誌序列號(binary)

@row_filter_option:篩選選項(nvarchar),可以是:

all:返回行最後的更改,不顯示更新掩碼的值.

all update old:返回行最後的更改,並顯示更新掩碼的值.

all with mask :返回行最後的更改和掩碼值.

all with merge :返回行最終的更改,不管是刪除還是合併操作(插入或者更新)插入和更新不會被打斷.由於用來確定給定更改的精確操作的邏輯會增加查詢的複雜性,所以,在只需指出應用更改數據所需的操作是插入還是更新但不必明確區分這兩者時,使用該選項可提高查詢性能.

 

5、sys.fn_cdc_get_min_lsn:返回指定捕獲實例的有效性間隔的低端點(start_lsn);

6、sys.fn_cdc_get_max_lsn:返回cdc.lsn_time_mapping系統表的最大日誌序列號(LSN);

 7、sys.fn_cdc_has_column_changed:標識指定的更新掩碼是否指示已更新關聯的更改行中的指定列;

參數:@source_schema:

@column_name:

@update_mask:(varbinary)

 

8、sys.fn_cdc_is_bit_set:返回指定掩碼和序號的行或列是否發生變更

參數:@position:行或列的位置序號(int)

@update_mask:二進制掩碼(varbinary)

使用此函數可以檢查某一列是否發生變更,比如要檢查變更實例表的第3列是否變更用 sys.fn_cdc_is_bit_set(3,__$update_mask) 如果返回1表示發生變更,返回0則該列沒有變化

 

9、sys.fn_cdc_get_column_ordinal:返回實例中的列是第幾列

參數:@capture_instance:

@column_name:列名(varchar)

 

最後給出一個示例:

 

USE SampleDatabase
GO

--在數據庫級別啓用CDC功能
EXEC sys.sp_cdc_enable_db 
--在需要做數據捕獲的表格上面啓用CDC功能
EXEC sys.sp_cdc_enable_table @source_schema='dbo',@source_name='Orders',@capture_instance='Orders',@supports_net_changes=0,@role_name=null
--插入或者更新數據測試CDC功能
INSERT Orders(CustomerID) VALUES('Microsoft');
INSERT Orders(CustomerID) VALUES('Google');
UPDATE Orders SET CustomerID='Yahoo' WHERE OrderID=1
DELETE FROM Orders WHERE OrderID=2
--查詢CDC的結果
SELECT * FROM cdc.Orders_CT

--按照時間範圍查詢CDC結果
DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
DECLARE @start_time DATETIME = '2011-8-10 00:00:00'
DECLARE @end_time DATETIME ='2011-8-11 00:00:00'
SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all')
--定義存儲過程來進行查詢
CREATE PROC GetOrdersCDCResult(@start_time DATETIME,@end_time DATETIME)
AS
BEGIN
    DECLARE @from_lsn BINARY(10),@end_lsn BINARY(10)
    SELECT @from_lsn=sys.fn_cdc_map_time_to_lsn('smallest greater than or equal',@start_time)
    SELECT @end_lsn=sys.fn_cdc_map_time_to_lsn(' largest less than or equal',@end_time)
    SELECT * FROM cdc.fn_cdc_get_all_changes_Orders(@from_lsn,@end_lsn,'all')
END
--執行存儲過程
EXEC GetOrdersCDCResult '2011-8-10','2011-8-11'
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章