关键词:CDC,数据库审计

详细参考:微软官网大神总结

原文:http://www.cnblogs.com/chenxizhang/archive/2011/08/10/2133408.html

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

CDC(Change Data Capture:变更数据捕获)这个功能是SQL Server 2008企业版的功能,它提供了一种新的机制,对表格数据的更新进行跟踪,在数据仓库的建设过程中,通过这种技术,可以简化从业务数据库导入数据的复杂度。

 

之前我有过两篇文章介绍,最近因为又在和有关客户介绍这方面的应用。发现之前的例子不是那么完整和清楚,特此再整理一篇出来,给大家参考

 

 

一、什么是CDC?

变更数据捕获(Change Data Capture ,简称 CDC)记录 SQL Server 表的插入、更新和删除活动。SQLServer的操作会写日志,这也是CDC捕获数据的来源。

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

开启cdc的源表在插入、更新和删除活动时会插入数据到日志表中。cdc通过捕获进程将变更数据捕获到变更表中,通过cdc提供的查询函数,我们可以捕获这部分数据。

二、开启CDC

2.1、开启CDC的必要条件

  • sqlserver 2008 以上版本

  • 需要开启代理服务(作业)

  • 磁盘要有足够的空间,保存日志文件

  • 表必须要有主键或者是唯一索引

2.2、开启数据库CDC

1、 在需要开启cdc的数据库上执行脚本如下:

if exists(select 1 from sys.databases where name='db_name' and is_cdc_enabled=0)
begin
    exec sys.sp_cdc_enable_db
end

2、查询数据库的cdc开启状态

select is_cdc_enabled from sys.databases where name='db_name'

查询结果为“1”,表示开启成功。

2.3、开启表CDC

*注意:表中必须有主键或者唯一索引

1、添加次要数据文件组及文件

数据库右键“属性” >> “文件组”>> ”添加”

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

“文件” >> “添加”

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

2、执行以下脚本,开启表cdc

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
--CDC是数据库文件组的名称
IF EXISTS(SELECT 1 FROM sys.tables WHERE name='table_name' AND is_tracked_by_cdc = 0)
BEGIN
    EXEC sys.sp_cdc_enable_table
        @source_schema = 'dbo', -- source_schema
        @source_name = 'table_name', -- table_name
        @capture_instance = NULL, -- capture_instance
        @supports_net_changes = 1, -- supports_net_changes
        @role_name = NULL, -- role_name
        @index_name = NULL, -- index_name
        @captured_column_list = NULL, -- captured_column_list
        @filegroup_name = 'CDC' -- filegroup_name
END
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

3、查看表cdc开启状态

SELECT is_tracked_by_cdc FROM sys.tables WHERE name='table_name'

查询结果为“1”,表示开启成功。

三、使用CDC

开启cdc后会在数据库中生成以下文件,开启数据库GY_DB,开启表VW_GHZDK

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

下面我们会对部分表和函数进行说明

系统表:

cdc.change_tables:表开启cdc后会插入一条数据到这张表中,记录表一些基本信息

cdc.captured_columns:开启cdc后的表,会记录它们的字段信息到这张表中

cdc.VW_GHZDK_CT(cdc.表名_CT):记录VW_GHZDK表中所有变更的数据

字段“__$operation”为“1”代表删除,“2”代表插入,“3”执行更新操作前的值,“4”执行更新操作后的值。字段“__$start_lsn”由于更改是来源于数据库的事务日志,所以这里会保存其事务日志的开始序列号(LSN)

函数:

cdc.fn_cdc_get_all_changes_dbo_VW_GHZDK:针对在指定日志序列号 (LSN) 范围内应用到源表的每项更改均返回一行。如果源行在该间隔内有多项更改,则每项更改都会表示在返回的结果集中

cdc.fn_cdc_get_net_changes_dbo_VW_GHZDK:针对指定 LSN 范围内每个已更改的源行返回一个净更改行。也就是说,如果在 LSN 范围内源行具有多项更改,则该函数将返回反映该行最终内容的单一行

sys.fn_cdc_map_time_to_lsn:为指定的时间返回 cdc.lsn_time_mapping 系统表中 start_lsn 列中的日志序列号 (LSN) 值。可以使用此函数系统地将日期时间范围映射到基于 LSN 的范围,以供变更数据捕获枚举函数 cdc.fn_cdc_get_all_changes_<capture_instance> 和 cdc.fn_cdc_get_net_changes_<capture_instance> 返回此范围内的数据更改。

 

 

 

四、最佳实践:案例演示

-----------------------------------

1. 准备一个数据库,里面准备一个表,Orders

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

2. 启用数据库级别的CDC选项

--在数据库级别启用CDC功能
EXEC sys.sp_cdc_enable_db 

这个命令执行完之后,会在系统表里面添加6个表格

    SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

3.在需要做数据捕获的表上面启用CDC选项

EXEC sys.sp_cdc_enable_table 
  @source_schema='dbo',
  @source_name='Orders',
  @capture_instance='Orders',
  @supports_net_changes=0,
  @role_name=null

 

【备注】关于这个存储过程的具体用法和有关参数的含义,请参考

http://msdn.microsoft.com/en-us/library/bb522475.aspx

 

执行之后,会有如下的输出消息

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

这个提示的意思是说,要启动SQL Server Agent。因为CDC功能是要通过一个两个作业来自动化完成的

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

与此同时,执行上面的命令还将在系统表中添加一个表格

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

还会添加一个函数

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

4.插入或者更新数据测试CDC功能

--插入或者更新数据测试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

 

这个范例插入两行数据,紧接着又对第一行更新,然后还删除了第二行,所以最终只有一行数据

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

那么,我们来看看CDC做了什么事情呢?

SELECT * FROM cdc.Orders_CT

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

我们可以来解释一下上面结果的含义

__$operation=2的情况,表示新增

__$operation=3或者4,表示更新,3表示旧值,4表示新值

__$operation=1的情况,表示删除

 

很好理解,不是吗?

但是,我们一般都是需要按照时间范围进行检索,对吧,所以,需要使用下面的语法进行查询

--按照时间范围查询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')

 

 

关于sys.fn_cdc_map_time_to_lsn这个函数,请参考

http://msdn.microsoft.com/en-us/library/bb500137.aspx

查询的结果如下

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

如果需要包含更新操作的旧值,则可以以下的语法

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 update old')

 

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

通常,为了方便起见,我们会将这个查询定义为一个存储过程,如下

--定义存储过程来进行查询
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'

 

5.结合SSIS实现事实表的增量更新

下面展示了一个SSIS 包的设计,这里面读取CDC的数据,先进行一些查找,然后按照__$operation的值拆分成为三个操作,分别进行插入,更新和删除,这样就可以实现对事实表的增量更新

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

 

【5】代码汇总

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'

 

【6】CDC的注意事项

【6.1】不能truncate

  truncate 了~会提示不能使用的哟~

【6.2】修改表结构的坑

测试数据

EXEC sys.sp_cdc_enable_db
CREATE TABLE AAA2
(
    ID INT PRIMARY KEY,
    Col1 NVARCHAR(50),
    Col2 INT
)

EXEC sys.sp_cdc_enable_table @source_schema = 'dbo', 
    @source_name = 'AAA2'

INSERT INTO dbo.AAA2( ID, Col1,Col2 ) VALUES  ( 1, 'pp',34 ),( 2, 'bb',234 ),( 3, 'cc',12 )

UPDATE dbo.AAA2 SET Col1 = 'dd'   WHERE ID = 3

DELETE FROM dbo.AAA2 WHERE ID = 2

SELECT * FROM cdc.dbo_AAA2_CT

__$start_lsn __$end_lsn __$seqval __$operation __$update_mask ID Col1 Col2 ---------------------- ------------- ---------------------- ------------ -------------------- ---- ------ ----------- 0x0000015B0001378F0019 NULL 0x0000015B0001378F0016 2 0x07 1 pp 34 0x0000015B0001378F0019 NULL 0x0000015B0001378F0017 2 0x07 2 bb 234 0x0000015B0001378F0019 NULL 0x0000015B0001378F0018 2 0x07 3 cc 12 0x0000015B000137A50003 NULL 0x0000015B000137A50002 3 0x02 3 cc 12 0x0000015B000137A50003 NULL 0x0000015B000137A50002 4 0x02 3 dd 12 0x0000015B000137AB0005 NULL 0x0000015B000137AB0002 1 0x07 2 bb 234

    栗子1 ,删除了一列Col2 然后再插入2条数据,然后还是会存在Col2的列(因为不需要改结构嘛╮(╯_╰)╭),然后跟踪的时候把值设置成空

ALTER TABLE dbo.AAA2 DROP COLUMN Col2

INSERT INTO dbo.AAA2
        ( ID, Col1 )
VALUES  ( 4, N'DD'),( 5, N'EE')

__$start_lsn    __$seqval    __$operation    __$update_mask    ID    Col1    Col2
0x0000015B000138F40004    0x0000015B000138F40002    2    0x07    4    DD    NULL
0x0000015B000138F40004    0x0000015B000138F40003    2    0x07    5    EE    NULL

 

 栗子2 ,然后我脑抽的重新把Col2 加进去~然而我改成了字符串类型,然后从新插入数据 ,Col2 没值啊!!!那也正常,因为这是就结构,虽然名字一样,但是ColumnID已经不一样了啊!所以追踪不到是很正常的。

ALTER TABLE dbo.AAA2 ADD Col2 NVARCHAR(50)

INSERT INTO dbo.AAA2
        ( ID, Col1, Col2 )
VALUES  ( 6, -- ID - int
          N'jj', -- Col1 - nvarchar(50)
          'jjj'  -- Col2 - int
          )

__$start_lsn    __$seqval    __$operation    __$update_mask    ID    Col1    Col2
0x0000015B000138F40004    0x0000015B000138F40002    2    0x07    4    DD    NULL
0x0000015B000138F40004    0x0000015B000138F40003    2    0x07    5    EE    NULL
0x0000015B000139640003    0x0000015B000139640002    2    0x07    6    jj    NULL

 

栗子3 ,那我更新总可以了吧!当更新的是元结构有的列,是可以更新成功的,但是如果是新列做了改动,则捕获不了,正常嘛(想想既然可以给你配置可跟踪的列,那么不存在这个列表里面的列发生变化不捕捉,就是这个道理罗~)

UPDATE dbo.AAA2 SET Col2 = 'ee' WHERE ID = 4
UPDATE dbo.AAA2 SET Col1 = 'III' WHERE ID = 6


__$start_lsn    __$seqval    __$operation    __$update_mask    ID    Col1    Col2
0x0000015B000139C00003    0x0000015B000139C00002    4    0x02    6    III    NULL

 

那该如何处理这个问题呢~

从心做一个捕获实例~从心做一个捕获实例~从心做一个捕获实例 重要的事情说3便 ╮(╯_╰)╭。也只有这样罗

 

 

 

 

原文:http://www.cnblogs.com/chenxizhang/archive/2011/08/10/2133408.html

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

CDC(Change Data Capture:变更数据捕获)这个功能是SQL Server 2008企业版的功能,它提供了一种新的机制,对表格数据的更新进行跟踪,在数据仓库的建设过程中,通过这种技术,可以简化从业务数据库导入数据的复杂度。

 

之前我有过两篇文章介绍,最近因为又在和有关客户介绍这方面的应用。发现之前的例子不是那么完整和清楚,特此再整理一篇出来,给大家参考

 

 

一、什么是CDC?

变更数据捕获(Change Data Capture ,简称 CDC)记录 SQL Server 表的插入、更新和删除活动。SQLServer的操作会写日志,这也是CDC捕获数据的来源。

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

开启cdc的源表在插入、更新和删除活动时会插入数据到日志表中。cdc通过捕获进程将变更数据捕获到变更表中,通过cdc提供的查询函数,我们可以捕获这部分数据。

二、开启CDC

2.1、开启CDC的必要条件

  • sqlserver 2008 以上版本

  • 需要开启代理服务(作业)

  • 磁盘要有足够的空间,保存日志文件

  • 表必须要有主键或者是唯一索引

2.2、开启数据库CDC

1、 在需要开启cdc的数据库上执行脚本如下:

if exists(select 1 from sys.databases where name='db_name' and is_cdc_enabled=0)
begin
    exec sys.sp_cdc_enable_db
end

2、查询数据库的cdc开启状态

select is_cdc_enabled from sys.databases where name='db_name'

查询结果为“1”,表示开启成功。

2.3、开启表CDC

*注意:表中必须有主键或者唯一索引

1、添加次要数据文件组及文件

数据库右键“属性” >> “文件组”>> ”添加”

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

“文件” >> “添加”

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

2、执行以下脚本,开启表cdc

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
--CDC是数据库文件组的名称
IF EXISTS(SELECT 1 FROM sys.tables WHERE name='table_name' AND is_tracked_by_cdc = 0)
BEGIN
    EXEC sys.sp_cdc_enable_table
        @source_schema = 'dbo', -- source_schema
        @source_name = 'table_name', -- table_name
        @capture_instance = NULL, -- capture_instance
        @supports_net_changes = 1, -- supports_net_changes
        @role_name = NULL, -- role_name
        @index_name = NULL, -- index_name
        @captured_column_list = NULL, -- captured_column_list
        @filegroup_name = 'CDC' -- filegroup_name
END
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

3、查看表cdc开启状态

SELECT is_tracked_by_cdc FROM sys.tables WHERE name='table_name'

查询结果为“1”,表示开启成功。

三、使用CDC

开启cdc后会在数据库中生成以下文件,开启数据库GY_DB,开启表VW_GHZDK

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

下面我们会对部分表和函数进行说明

系统表:

cdc.change_tables:表开启cdc后会插入一条数据到这张表中,记录表一些基本信息

cdc.captured_columns:开启cdc后的表,会记录它们的字段信息到这张表中

cdc.VW_GHZDK_CT(cdc.表名_CT):记录VW_GHZDK表中所有变更的数据

字段“__$operation”为“1”代表删除,“2”代表插入,“3”执行更新操作前的值,“4”执行更新操作后的值。字段“__$start_lsn”由于更改是来源于数据库的事务日志,所以这里会保存其事务日志的开始序列号(LSN)

函数:

cdc.fn_cdc_get_all_changes_dbo_VW_GHZDK:针对在指定日志序列号 (LSN) 范围内应用到源表的每项更改均返回一行。如果源行在该间隔内有多项更改,则每项更改都会表示在返回的结果集中

cdc.fn_cdc_get_net_changes_dbo_VW_GHZDK:针对指定 LSN 范围内每个已更改的源行返回一个净更改行。也就是说,如果在 LSN 范围内源行具有多项更改,则该函数将返回反映该行最终内容的单一行

sys.fn_cdc_map_time_to_lsn:为指定的时间返回 cdc.lsn_time_mapping 系统表中 start_lsn 列中的日志序列号 (LSN) 值。可以使用此函数系统地将日期时间范围映射到基于 LSN 的范围,以供变更数据捕获枚举函数 cdc.fn_cdc_get_all_changes_<capture_instance> 和 cdc.fn_cdc_get_net_changes_<capture_instance> 返回此范围内的数据更改。

 

 

 

四、最佳实践:案例演示

-----------------------------------

1. 准备一个数据库,里面准备一个表,Orders

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

2. 启用数据库级别的CDC选项

--在数据库级别启用CDC功能
EXEC sys.sp_cdc_enable_db 

这个命令执行完之后,会在系统表里面添加6个表格

    SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

3.在需要做数据捕获的表上面启用CDC选项

EXEC sys.sp_cdc_enable_table 
  @source_schema='dbo',
  @source_name='Orders',
  @capture_instance='Orders',
  @supports_net_changes=0,
  @role_name=null

 

【备注】关于这个存储过程的具体用法和有关参数的含义,请参考

http://msdn.microsoft.com/en-us/library/bb522475.aspx

 

执行之后,会有如下的输出消息

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

这个提示的意思是说,要启动SQL Server Agent。因为CDC功能是要通过一个两个作业来自动化完成的

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

与此同时,执行上面的命令还将在系统表中添加一个表格

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

还会添加一个函数

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

4.插入或者更新数据测试CDC功能

--插入或者更新数据测试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

 

这个范例插入两行数据,紧接着又对第一行更新,然后还删除了第二行,所以最终只有一行数据

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

那么,我们来看看CDC做了什么事情呢?

SELECT * FROM cdc.Orders_CT

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

我们可以来解释一下上面结果的含义

__$operation=2的情况,表示新增

__$operation=3或者4,表示更新,3表示旧值,4表示新值

__$operation=1的情况,表示删除

 

很好理解,不是吗?

但是,我们一般都是需要按照时间范围进行检索,对吧,所以,需要使用下面的语法进行查询

--按照时间范围查询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')

 

 

关于sys.fn_cdc_map_time_to_lsn这个函数,请参考

http://msdn.microsoft.com/en-us/library/bb500137.aspx

查询的结果如下

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

如果需要包含更新操作的旧值,则可以以下的语法

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 update old')

 

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

通常,为了方便起见,我们会将这个查询定义为一个存储过程,如下

--定义存储过程来进行查询
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'

 

5.结合SSIS实现事实表的增量更新

下面展示了一个SSIS 包的设计,这里面读取CDC的数据,先进行一些查找,然后按照__$operation的值拆分成为三个操作,分别进行插入,更新和删除,这样就可以实现对事实表的增量更新

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

 

【5】代码汇总

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'

 

【6】CDC的注意事项

【6.1】不能truncate

  truncate 了~会提示不能使用的哟~

【6.2】修改表结构的坑

测试数据

EXEC sys.sp_cdc_enable_db
CREATE TABLE AAA2
(
    ID INT PRIMARY KEY,
    Col1 NVARCHAR(50),
    Col2 INT
)

EXEC sys.sp_cdc_enable_table @source_schema = 'dbo', 
    @source_name = 'AAA2'

INSERT INTO dbo.AAA2( ID, Col1,Col2 ) VALUES  ( 1, 'pp',34 ),( 2, 'bb',234 ),( 3, 'cc',12 )

UPDATE dbo.AAA2 SET Col1 = 'dd'   WHERE ID = 3

DELETE FROM dbo.AAA2 WHERE ID = 2

SELECT * FROM cdc.dbo_AAA2_CT

__$start_lsn __$end_lsn __$seqval __$operation __$update_mask ID Col1 Col2 ---------------------- ------------- ---------------------- ------------ -------------------- ---- ------ ----------- 0x0000015B0001378F0019 NULL 0x0000015B0001378F0016 2 0x07 1 pp 34 0x0000015B0001378F0019 NULL 0x0000015B0001378F0017 2 0x07 2 bb 234 0x0000015B0001378F0019 NULL 0x0000015B0001378F0018 2 0x07 3 cc 12 0x0000015B000137A50003 NULL 0x0000015B000137A50002 3 0x02 3 cc 12 0x0000015B000137A50003 NULL 0x0000015B000137A50002 4 0x02 3 dd 12 0x0000015B000137AB0005 NULL 0x0000015B000137AB0002 1 0x07 2 bb 234

    栗子1 ,删除了一列Col2 然后再插入2条数据,然后还是会存在Col2的列(因为不需要改结构嘛╮(╯_╰)╭),然后跟踪的时候把值设置成空

ALTER TABLE dbo.AAA2 DROP COLUMN Col2

INSERT INTO dbo.AAA2
        ( ID, Col1 )
VALUES  ( 4, N'DD'),( 5, N'EE')

__$start_lsn    __$seqval    __$operation    __$update_mask    ID    Col1    Col2
0x0000015B000138F40004    0x0000015B000138F40002    2    0x07    4    DD    NULL
0x0000015B000138F40004    0x0000015B000138F40003    2    0x07    5    EE    NULL

 

 栗子2 ,然后我脑抽的重新把Col2 加进去~然而我改成了字符串类型,然后从新插入数据 ,Col2 没值啊!!!那也正常,因为这是就结构,虽然名字一样,但是ColumnID已经不一样了啊!所以追踪不到是很正常的。

ALTER TABLE dbo.AAA2 ADD Col2 NVARCHAR(50)

INSERT INTO dbo.AAA2
        ( ID, Col1, Col2 )
VALUES  ( 6, -- ID - int
          N'jj', -- Col1 - nvarchar(50)
          'jjj'  -- Col2 - int
          )

__$start_lsn    __$seqval    __$operation    __$update_mask    ID    Col1    Col2
0x0000015B000138F40004    0x0000015B000138F40002    2    0x07    4    DD    NULL
0x0000015B000138F40004    0x0000015B000138F40003    2    0x07    5    EE    NULL
0x0000015B000139640003    0x0000015B000139640002    2    0x07    6    jj    NULL

 

栗子3 ,那我更新总可以了吧!当更新的是元结构有的列,是可以更新成功的,但是如果是新列做了改动,则捕获不了,正常嘛(想想既然可以给你配置可跟踪的列,那么不存在这个列表里面的列发生变化不捕捉,就是这个道理罗~)

UPDATE dbo.AAA2 SET Col2 = 'ee' WHERE ID = 4
UPDATE dbo.AAA2 SET Col1 = 'III' WHERE ID = 6


__$start_lsn    __$seqval    __$operation    __$update_mask    ID    Col1    Col2
0x0000015B000139C00003    0x0000015B000139C00002    4    0x02    6    III    NULL

 

那该如何处理这个问题呢~

从心做一个捕获实例~从心做一个捕获实例~从心做一个捕获实例 重要的事情说3便 ╮(╯_╰)╭。也只有这样罗

 

 

 

 

CDC(Change Data Capture:变更数据捕获)这个功能是SQL Server 2008企业版的功能,它提供了一种新的机制,对表格数据的更新进行跟踪,在数据仓库的建设过程中,通过这种技术,可以简化从业务数据库导入数据的复杂度。

 

之前我有过两篇文章介绍,最近因为又在和有关客户介绍这方面的应用。发现之前的例子不是那么完整和清楚,特此再整理一篇出来,给大家参考

 

 

一、什么是CDC?

变更数据捕获(Change Data Capture ,简称 CDC)记录 SQL Server 表的插入、更新和删除活动。SQLServer的操作会写日志,这也是CDC捕获数据的来源。

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

开启cdc的源表在插入、更新和删除活动时会插入数据到日志表中。cdc通过捕获进程将变更数据捕获到变更表中,通过cdc提供的查询函数,我们可以捕获这部分数据。

二、开启CDC

2.1、开启CDC的必要条件

  • sqlserver 2008 以上版本

  • 需要开启代理服务(作业)

  • 磁盘要有足够的空间,保存日志文件

  • 表必须要有主键或者是唯一索引

2.2、开启数据库CDC

1、 在需要开启cdc的数据库上执行脚本如下:

if exists(select 1 from sys.databases where name='db_name' and is_cdc_enabled=0)
begin
    exec sys.sp_cdc_enable_db
end

2、查询数据库的cdc开启状态

select is_cdc_enabled from sys.databases where name='db_name'

查询结果为“1”,表示开启成功。

2.3、开启表CDC

*注意:表中必须有主键或者唯一索引

1、添加次要数据文件组及文件

数据库右键“属性” >> “文件组”>> ”添加”

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

“文件” >> “添加”

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

2、执行以下脚本,开启表cdc

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
--CDC是数据库文件组的名称
IF EXISTS(SELECT 1 FROM sys.tables WHERE name='table_name' AND is_tracked_by_cdc = 0)
BEGIN
    EXEC sys.sp_cdc_enable_table
        @source_schema = 'dbo', -- source_schema
        @source_name = 'table_name', -- table_name
        @capture_instance = NULL, -- capture_instance
        @supports_net_changes = 1, -- supports_net_changes
        @role_name = NULL, -- role_name
        @index_name = NULL, -- index_name
        @captured_column_list = NULL, -- captured_column_list
        @filegroup_name = 'CDC' -- filegroup_name
END
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

3、查看表cdc开启状态

SELECT is_tracked_by_cdc FROM sys.tables WHERE name='table_name'

查询结果为“1”,表示开启成功。

三、使用CDC

开启cdc后会在数据库中生成以下文件,开启数据库GY_DB,开启表VW_GHZDK

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

下面我们会对部分表和函数进行说明

系统表:

cdc.change_tables:表开启cdc后会插入一条数据到这张表中,记录表一些基本信息

cdc.captured_columns:开启cdc后的表,会记录它们的字段信息到这张表中

cdc.VW_GHZDK_CT(cdc.表名_CT):记录VW_GHZDK表中所有变更的数据

字段“__$operation”为“1”代表删除,“2”代表插入,“3”执行更新操作前的值,“4”执行更新操作后的值。字段“__$start_lsn”由于更改是来源于数据库的事务日志,所以这里会保存其事务日志的开始序列号(LSN)

函数:

cdc.fn_cdc_get_all_changes_dbo_VW_GHZDK:针对在指定日志序列号 (LSN) 范围内应用到源表的每项更改均返回一行。如果源行在该间隔内有多项更改,则每项更改都会表示在返回的结果集中

cdc.fn_cdc_get_net_changes_dbo_VW_GHZDK:针对指定 LSN 范围内每个已更改的源行返回一个净更改行。也就是说,如果在 LSN 范围内源行具有多项更改,则该函数将返回反映该行最终内容的单一行

sys.fn_cdc_map_time_to_lsn:为指定的时间返回 cdc.lsn_time_mapping 系统表中 start_lsn 列中的日志序列号 (LSN) 值。可以使用此函数系统地将日期时间范围映射到基于 LSN 的范围,以供变更数据捕获枚举函数 cdc.fn_cdc_get_all_changes_<capture_instance> 和 cdc.fn_cdc_get_net_changes_<capture_instance> 返回此范围内的数据更改。

 

 

 

四、最佳实践:案例演示

-----------------------------------

1. 准备一个数据库,里面准备一个表,Orders

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

2. 启用数据库级别的CDC选项

--在数据库级别启用CDC功能
EXEC sys.sp_cdc_enable_db 

这个命令执行完之后,会在系统表里面添加6个表格

    SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

3.在需要做数据捕获的表上面启用CDC选项

EXEC sys.sp_cdc_enable_table 
  @source_schema='dbo',
  @source_name='Orders',
  @capture_instance='Orders',
  @supports_net_changes=0,
  @role_name=null

 

【备注】关于这个存储过程的具体用法和有关参数的含义,请参考

http://msdn.microsoft.com/en-us/library/bb522475.aspx

 

执行之后,会有如下的输出消息

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

这个提示的意思是说,要启动SQL Server Agent。因为CDC功能是要通过一个两个作业来自动化完成的

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

与此同时,执行上面的命令还将在系统表中添加一个表格

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

还会添加一个函数

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

4.插入或者更新数据测试CDC功能

--插入或者更新数据测试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

 

这个范例插入两行数据,紧接着又对第一行更新,然后还删除了第二行,所以最终只有一行数据

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

那么,我们来看看CDC做了什么事情呢?

SELECT * FROM cdc.Orders_CT

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

我们可以来解释一下上面结果的含义

__$operation=2的情况,表示新增

__$operation=3或者4,表示更新,3表示旧值,4表示新值

__$operation=1的情况,表示删除

 

很好理解,不是吗?

但是,我们一般都是需要按照时间范围进行检索,对吧,所以,需要使用下面的语法进行查询

--按照时间范围查询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')

 

 

关于sys.fn_cdc_map_time_to_lsn这个函数,请参考

http://msdn.microsoft.com/en-us/library/bb500137.aspx

查询的结果如下

SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

如果需要包含更新操作的旧值,则可以以下的语法

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 update old')

 

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

通常,为了方便起见,我们会将这个查询定义为一个存储过程,如下

--定义存储过程来进行查询
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'

 

5.结合SSIS实现事实表的增量更新

下面展示了一个SSIS 包的设计,这里面读取CDC的数据,先进行一些查找,然后按照__$operation的值拆分成为三个操作,分别进行插入,更新和删除,这样就可以实现对事实表的增量更新

  SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    


            
SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑

 

 

【5】代码汇总

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'

 

【6】CDC的注意事项

【6.1】不能truncate

  truncate 了~会提示不能使用的哟~

【6.2】修改表结构的坑

测试数据

EXEC sys.sp_cdc_enable_db
CREATE TABLE AAA2
(
    ID INT PRIMARY KEY,
    Col1 NVARCHAR(50),
    Col2 INT
)

EXEC sys.sp_cdc_enable_table @source_schema = 'dbo', 
    @source_name = 'AAA2'

INSERT INTO dbo.AAA2( ID, Col1,Col2 ) VALUES  ( 1, 'pp',34 ),( 2, 'bb',234 ),( 3, 'cc',12 )

UPDATE dbo.AAA2 SET Col1 = 'dd'   WHERE ID = 3

DELETE FROM dbo.AAA2 WHERE ID = 2

SELECT * FROM cdc.dbo_AAA2_CT

__$start_lsn __$end_lsn __$seqval __$operation __$update_mask ID Col1 Col2 ---------------------- ------------- ---------------------- ------------ -------------------- ---- ------ ----------- 0x0000015B0001378F0019 NULL 0x0000015B0001378F0016 2 0x07 1 pp 34 0x0000015B0001378F0019 NULL 0x0000015B0001378F0017 2 0x07 2 bb 234 0x0000015B0001378F0019 NULL 0x0000015B0001378F0018 2 0x07 3 cc 12 0x0000015B000137A50003 NULL 0x0000015B000137A50002 3 0x02 3 cc 12 0x0000015B000137A50003 NULL 0x0000015B000137A50002 4 0x02 3 dd 12 0x0000015B000137AB0005 NULL 0x0000015B000137AB0002 1 0x07 2 bb 234

    栗子1 ,删除了一列Col2 然后再插入2条数据,然后还是会存在Col2的列(因为不需要改结构嘛╮(╯_╰)╭),然后跟踪的时候把值设置成空

ALTER TABLE dbo.AAA2 DROP COLUMN Col2

INSERT INTO dbo.AAA2
        ( ID, Col1 )
VALUES  ( 4, N'DD'),( 5, N'EE')

__$start_lsn    __$seqval    __$operation    __$update_mask    ID    Col1    Col2
0x0000015B000138F40004    0x0000015B000138F40002    2    0x07    4    DD    NULL
0x0000015B000138F40004    0x0000015B000138F40003    2    0x07    5    EE    NULL

 

 栗子2 ,然后我脑抽的重新把Col2 加进去~然而我改成了字符串类型,然后从新插入数据 ,Col2 没值啊!!!那也正常,因为这是就结构,虽然名字一样,但是ColumnID已经不一样了啊!所以追踪不到是很正常的。

ALTER TABLE dbo.AAA2 ADD Col2 NVARCHAR(50)

INSERT INTO dbo.AAA2
        ( ID, Col1, Col2 )
VALUES  ( 6, -- ID - int
          N'jj', -- Col1 - nvarchar(50)
          'jjj'  -- Col2 - int
          )

__$start_lsn    __$seqval    __$operation    __$update_mask    ID    Col1    Col2
0x0000015B000138F40004    0x0000015B000138F40002    2    0x07    4    DD    NULL
0x0000015B000138F40004    0x0000015B000138F40003    2    0x07    5    EE    NULL
0x0000015B000139640003    0x0000015B000139640002    2    0x07    6    jj    NULL

 

栗子3 ,那我更新总可以了吧!当更新的是元结构有的列,是可以更新成功的,但是如果是新列做了改动,则捕获不了,正常嘛(想想既然可以给你配置可跟踪的列,那么不存在这个列表里面的列发生变化不捕捉,就是这个道理罗~)

UPDATE dbo.AAA2 SET Col2 = 'ee' WHERE ID = 4
UPDATE dbo.AAA2 SET Col1 = 'III' WHERE ID = 6


__$start_lsn    __$seqval    __$operation    __$update_mask    ID    Col1    Col2
0x0000015B000139C00003    0x0000015B000139C00002    4    0x02    6    III    NULL

 

那该如何处理这个问题呢~

从心做一个捕获实例~从心做一个捕获实例~从心做一个捕获实例 重要的事情说3便 ╮(╯_╰)╭。也只有这样罗

 

 

 

 

相关文章: