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'
 

发布了41 篇原创文章 · 获赞 9 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/jian200801/article/details/7395166