网站导航网学 原创论文 原创专题 网站设计 最新系统 原创论文 论文降重 发表论文 论文发表 UI设计定制 论文答辩PPT格式排版 期刊发表 论文专题
返回网学首页
网学原创论文
最新论文 推荐专题 热门论文 论文专题
当前位置: 网学 > 设计资源 > 数据库 > 正文

SQLSERVER2008异步捕获表数据修改

论文降重修改服务、格式排版等 获取论文 论文降重及排版 论文发表 相关服务

SQL server 2008为异步跟踪所有发生在用户表上的数据修改提供了内建的方法,而不需要编写自定义的触发器或者查询,变更数据捕获拥有最小性能开销,可以用于其它数据源的持续更新,例如,将OLTP数据库中的数据变更迁移到数据仓库数据库.

  1. /* 
  2.   1 建立测试数据库 
  3. */ 
  4. IF NOT EXISTS (SELECT NAME FROM SYS.databases WHERE name='CDC_TEST_DB'
  5.   
  6. BEGIN 
  7.     CREATE DATABASE CDC_TEST_DB 
  8. END 
  9.   
  10. /* 
  11.   2 在把CDC增加到CDC_TEST_DB数据库的表中,首先应该验证数据库是否启用了数据 
  12.     捕获 
  13. */ 
  14.   
  15.     --验证是否开启 
  16.     SELECT IS_CDC_ENABLED FROM SYS.databases WHERE name='CDC_TEST_DB' 
  17.     /* 
  18.     IS_CDC_ENABLED 
  19.     -------------- 
  20.     0 
  21.   
  22.     (1 行受影响) 
  23.     */ 
  24.     
  25.     --启用数据变更,在CDC_TEST_DB数据库中执行SYS.SP_CDC_ENABLE_DB存储过程: 
  26.     
  27.     USE CDC_TEST_DB 
  28.     GO 
  29.     
  30.     EXEC sys.SP_CDC_ENABLE_DB 
  31.     GO 
  32.     
  33.     /* 
  34.       CDC_TEST_DB开启数据捕获后,你将会在CDC_TEST_DB->安全性->架构下面看到新 
  35.       建立了一个CDC架构. 
  36.       
  37.       同样在CDC_TEST_DB会建立一些CDC架构的下的系统表: 
  38.        cdc.captured_columns 
  39.        返回指定的跟踪列 
  40.        
  41.        cdc.change_tables 
  42.        返回启用CDC的表.使用sys.sp_cdc_help_change_data_capture比直接查询好. 
  43.        
  44.        cdc.ddl_history 
  45.        返回每个表再启用CDC后的DDL变更.可以使用sys.sp_cdc_get_ddl_history代替查询该表. 
  46.        
  47.        cdc.index_columns 
  48.        返回启用CDC的表的相关索引列.同样用sys.sp_cdc_help_change_data_capure来获取比较好. 
  49.        
  50.        cdc.lsn_time_mapping 
  51.        为每个在更改表中存在行的事务返回一行.该表用于在日志序列号(LSN) 提交值和提交事务的时间之间建立映射. 
  52.        要避免直接查询该表,使用sys.fn_cdc_map_lsn_to_time和sys.fn_cdc_map_time_to_lsn函数. 
  53.          
  54.     */ 
  55.     
  56.     --下面再验证看看是否已经开启数据库开启 
  57.     SELECT IS_CDC_ENABLED FROM SYS.databases WHERE name='CDC_TEST_DB' 
  58.     
  59.     /* 
  60.     IS_CDC_ENABLED 
  61.     -------------- 
  62.     1 
  63.   
  64.     (1 行受影响) 
  65.     */ 
  66.   
  67. /* 
  68.   3 开启数据捕获之后,可以在数据库中通过使用SYS.SP_CDC_ENABLE_TABLE系统SP对表进行 
  69.      变更捕获.SP描述如下 
  70.        sys.sp_cdc_enable_table 
  71.        [ @source_schema = ] 'source_schema'
  72.        [ @source_name = ] 'source_name' , 
  73.        [ @role_name = ] 'role_name' 
  74.        [,[ @capture_instance = ] 'capture_instance' ] 
  75.        [,[ @supports_net_changes = ] supports_net_changes ] 
  76.        [,[ @index_name = ] 'index_name' ] 
  77.        [,[ @captured_column_list = ] 'captured_column_list' ] 
  78.        [,[ @filegroup_name = ] 'filegroup_name' ] 
  79.        [,[ @allow_partition_switch = ] 'partition_switch' ] 
  80.     
  81.     @source_schema : 
  82.     是源表所属的架构的名称.source_schema 的数据类型为sysname,无默认值,并且 
  83.     不能为NULL
  84.   
  85.     @source_name : 
  86.     是对其启用变更数据捕获的源表的名称.source_name 的数据类型为sysname,无默 
  87.     认值,并且不能为NULL.   source_name 必须存在于当前数据库中.不能对cdc 架构 
  88.     中的表启用变更数据捕获. 
  89.   
  90.     @role_name : 
  91.     是用于控制更改数据访问的数据库角色的名称.role_name 为sysname,并且必须指定. 
  92.     如果显式设置为NULL,则没有控制角色用于限制对更改数据的访问.如果当前存在该角 
  93.     色,则使用它.如果不存在该角色,则会尝试创建具有指定名称的数据库角色.在尝试创 
  94.     建该角色之前,将删除角色名称字符串右侧的空格.如果调用方无权在数据库中创建角色, 
  95.     则存储过程操作将失败. 
  96.   
  97.     @capture_instance : 
  98.     是用于命名特定于实例的变更数据捕获对象的捕获实例的名称.capture_instance 为 
  99.     sysname,并且不能为NULL.源表最多可以有两个捕获实例. 
  100.   
  101.     @supports_net_changes : 
  102.     指示是否对此捕获实例启用净更改查询支持.supports_net_changes 为bit,如果此表有 
  103.     主键,或者有已使用@index_name 参数进行标识的唯一索引,则此参数的默认值为1.否 
  104.     则,此参数默认为0.如果为0,则只生成查询所有更改的支持函数.如果为1,则还会生 
  105.     成查询净更改所需的函数. 
  106.   
  107.     如果将supports_net_changes 设置为1,则必须指定index_name,或者源表必须具有已 
  108.     定义的主键. 
  109.   
  110.     @index_name : 
  111.     用于唯一标识源表中的行的唯一索引的名称.index_name 为sysname,并且可以为NULL.如 
  112.     果指定,则index_name 必须是源表的唯一有效索引.如果指定index_name,则标识的索引列 
  113.     优先于任何定义的主键列,就像表的唯一行标识符一样.  
  114.     
  115.     @captured_column_list : 
  116.     标识将包括在更改表中的源表列.captured_column_list 的数据类型为nvarchar(max),并且 
  117.     可以为NULL.如果为NULL,则所有列都将包括在更改表中. 
  118.   
  119.     @filegroup_name : 这个选项允许指定CDC的数据存储到哪里.filegroup_name 为sysname,并且 
  120.     可以NULL.如果指定   ,则必须为当前数据库定义filegroup_name.如果为NULL,则使用默认文 
  121.     件组.   对于大型数据集,通过不同的文件组进行分隔会带来更好的管理型和性能. 
  122.   
  123.     @allow_partition_switch : 指示是否可以对启用了变更数据捕获的表执行ALTER TABLE 的SWITCH 
  124.     PARTITION 命令.allow_partition_switch 为bit,默认值为1. 
  125.   
  126.   
  127. */ 
  128.   
  129.   
  130.     --创建测试表 
  131.     
  132.     CREATE TABLE TB_CDC_USER( 
  133.        USERID  INT NOT NULL PRIMARY KEY  IDENTITY(1,1) 
  134.        ,NAME VARCHAR(20) NOT NULL 
  135.        ,ADDRESS  VARCHAR(100) NOT NULL
  136.        
  137.     
  138.     INSERT TB_CDC_USER(NAME,ADDRESS) VALUES 
  139.     ('香蕉','dss省fdfd市'), 
  140.     ('鸽子','山东省青岛市'), 
  141.     ('水哥','江苏省苏州市'), 
  142.     ('土豆','XX省XX市'); 
  143.     
  144.     
  145.     --捕获所有行发生的变更,只返回行的净变更.其它为默认值 
  146.     
  147.     EXEC sys.sp_cdc_enable_table 
  148.        @source_schema ='dbo' 
  149.        ,@source_name='TB_CDC_USER' 
  150.        ,@role_name=null 
  151.        ,@capture_instance=null 
  152.        ,@supports_net_changes=1 
  153.        ,@index_name=null 
  154.        ,@captured_column_list=null 
  155.        ,@filegroup_name=default 
  156.        ,@allow_partition_switch=1 
  157. /*     
  158.     执行后会启动个作业,每个启用表CDC的都会启用以下个作业. 
  159.     如果已经存在启用了CDC的表,则作业不会被重建 
  160.       
  161.        cdc.CDC_TEST_DB_capture  捕获作业 
  162.            该作业的职责是使用日志读取器技术捕获发生的变更,并且在 
  163.            SQLSERVER启动并运行时设定为自动运行.当JOB运行的时候会 
  164.            调用系统SP sys.sp_MScdc_capture_job,该sp内部调用调用 
  165.            sys.sp_cdc_scan.如果变更数据捕获日志扫描操作已经处于 
  166.            活动状态,或数据库启用了事务复制,则无法显式执行此过程. 
  167.            此存储过程应当由需要自定义自动配置的捕获作业的行为的管 
  168.            理员使用. 
  169.   
  170.        
  171.        cdc.CDC_TEST_DB_cleanup  清除作业 
  172.            默认为每天上午点运行,默认是清除存放天以上的数据. 
  173.            调用系统存储过程sys.sp_MScdc_cleanup_job 
  174.            
  175.     
  176.     执行成功之后同样在CDC_TEST_DB数据库系统表中会生成表cdc.dbo_TB_CDC_USER_CT, 
  177.     该表包含TB_CDC_USER_CT表上所有的变更.展开表后会发现新增加了列. 
  178.        __$start_lsn  与相应更改的提交事务关联的日志序列号(LSN). 
  179.        __$end_lsn 
  180.         __$seqval     用于对事务内的行更改进行排序的序列值. 
  181.        __$operation 识与相应更改关联的数据操作语言(DML) 操作.可以是下列值之一: 
  182.                      1 = 删除;2 = 插入;3 = 更新(旧值)列数据中具有执行更新语句之 
  183.                      前的行值.4 = 更新(新值)列数据中具有执行更新语句之后的行值. 
  184.   
  185.                   
  186.        __$update_mask    基于更改表的列序号的位掩码,用于标识那些发生更改的列。 
  187.        
  188.     其中很重要的列__$operation and __$update_mask 
  189.        
  190. */ 
  191.     
  192.     
  193. /* 
  194.     通过下面的查询确认这个表已经被跟踪 
  195. */  
  196.     SELECT is_tracked_by_cdc 
  197.     FROM SYS.TABLES 
  198.     WHERE NAME='TB_CDC_USER' 
  199.          AND SCHEMA_ID=SCHEMA_ID('DBO'
  200. /*    
  201.     is_tracked_by_cdc 
  202.     ----------------- 
  203.     1 
  204.   
  205.     (1 行受影响) 
  206. */ 
  207.   
  208.   
  209. /* 
  210.     也可以使用sys.sp_cdc_help_change_data_capture来验证数据捕获的配置. 
  211.        sys.sp_cdc_help_change_data_capture 
  212.          [ [ @source_schema = ] 'source_schema' ]--表的架构名 
  213.          [, [ @source_name = ] 'source_name' ]      --表名称 
  214. */ 
  215.     
  216.     EXEC sys.sp_cdc_help_change_data_capture 'DBO','TB_CDC_USER' 
  217. /*  
  218.     查询结果: 
  219.     source_schema            dbo 
  220.     source_table             TB_CDC_USER 
  221.     capture_instance         dbo_TB_CDC_USER 
  222.     object_id                373576369 
  223.     source_object_id start_lsn  309576141 
  224.     end_lsn                     0x0000001A000001CE003B 
  225.     supports_net_changes     NULL 
  226.     has_drop_pending         1 
  227.     role_name                NULL 
  228.     index_name               NULL 
  229.     filegroup_name              PK__TB_CDC_U__7B9E7F35145C0A3F 
  230.     create_date                 2010-05-20 11:48:58.177 
  231.     index_column_list        [USERID] 
  232.     captured_column_list     [USERID], [NAME], [ADDRESS] 
  233. */ 
  234.   
  235.   
  236.   
  237. /* 
  238.   4 进行变更捕获测试. 
  239.   
  240.      先查看那表中都写什么数据. 
  241. */ 
  242.   
  243.        USE CDC_TEST_DB 
  244.        GO 
  245.        SELECT * 
  246.        FROM dbo.TB_CDC_USER 
  247.        GO 
  248.   
  249.        SELECT * 
  250.        FROM cdc.dbo_TB_CDC_USER_CT 
  251.        GO 
  252.   
  253.        /*结果 
  254.        USERID      NAME                 ADDRESS 
  255.        ----------- -------------------- ------------------ 
  256.        1           香蕉                  dss省fdfd市 
  257.        2           鸽子                  山东省青岛市 
  258.        3           水哥                  江苏省苏州市 
  259.        4           土豆                  XX省XX市 
  260.   
  261.        (4 行受影响) 
  262.   
  263.        __$start_lsn  __$end_lsn   __$seqval __$operation __$update_mask USERID  NAME  ADDRESS 
  264.        ------------- -----------  --------- ------------ -------------- ------- ----- -------- 
  265.   
  266.        (0 行受影响) 
  267.        */ 
  268.   
  269.     
  270.     --  4.1 插入操作 
  271.     
  272.     USE CDC_TEST_DB 
  273.     GO 
  274.        
  275.     INSERT TB_CDC_USER(NAME,ADDRESS) VALUES 
  276.     ('九零后','毛毛省毛毛市'
  277.     
  278.     
  279.     SELECT * 
  280.     FROM dbo.TB_CDC_USER 
  281.     GO 
  282.   
  283.     SELECT * 
  284.     FROM cdc.dbo_TB_CDC_USER_CT 
  285.     GO 
  286.     /* 
  287.     USERID      NAME                 ADDRESS 
  288.     ----------- -------------------- --------------------- 
  289.     1           香蕉                  dss省fdfd市 
  290.     2           鸽子                  山东省青岛市 
  291.     3           水哥                  江苏省苏州市 
  292.     4           土豆                  XX省XX市 
  293.     5           九零后                 毛毛省毛毛市 
  294.   
  295.     (5 行受影响) 
  296.   
  297.     __$start_lsn         __$end_lsn __$seqval            __$operation  __$update_mask    USERID  NAME   ADDRESS 
  298.     ----------------------   ----------- --------------------- ------------  --------------    ------- ------    ------------ 
  299.     0x0000002C000001E30004   NULL       0x0000002C000001E30003   2             0x07          5       九零后  毛毛省毛毛市 
  300.     
  301.     (1 行受影响) 
  302.     
  303.     上面的结果中看出当TB_CDC_USER插入一条数据后,同样在跟踪表中可以有一条相同的数据_operation 
  304.     值为代表这是一条插入操作. 
  305.     */ 
  306.     
  307.     
  308.     --4.2更新操作 
  309.     
  310.     USE CDC_TEST_DB 
  311.     GO 
  312.        
  313.     UPDATE TB_CDC_USER 
  314.     SET ADDRESS='YY省YY市' 
  315.     WHERE USERID=5 
  316.     
  317.     SELECT * 
  318.     FROM dbo.TB_CDC_USER 
  319.     GO 
  320.   
  321.     SELECT * 
  322.     FROM cdc.dbo_TB_CDC_USER_CT 
  323.     GO 
  324.     
  325.     /*结果 
  326.     USERID      NAME                 ADDRESS 
  327.     ----------- -------------------- --------------- 
  328.     1           香蕉                  dss省fdfd市 
  329.     2           鸽子                  山东省青岛市 
  330.     3           水哥                  江苏省苏州市 
  331.     4           土豆                  XX省XX市 
  332.     5           九零后                 YY省YY市 
  333.   
  334.     (5 行受影响) 
  335.   
  336.     __$start_lsn         __$end_lsn __$seqval            __$operation  __$update_mask    USERID  NAME   ADDRESS 
  337.     ----------------------   ----------- --------------------- ------------  --------------    ------- ------    ------------ 
  338.     0x0000002C000001E30004   NULL       0x0000002C000001E30003   2             0x07          5       九零后  毛毛省毛毛市 
  339.     0x0000002D0000004D0004   NULL       0x0000002D0000004D0002   3             0x04          5       九零后  毛毛省毛毛市 
  340.     0x0000002D0000004D0004   NULL       0x0000002D0000004D0002   4             0x04          5       九零后  YY省YY市 
  341.   
  342.   
  343.     同样我们查询dbo_TB_CDC_USER_CT后会发现比之前多了条数据,分别为USERID=6这条数据更新 
  344.     前和更新后的数据,__$operation为代表UPDATE前的数据,4为UPDATE后的数据.如果是多列数据 
  345.     一起更新同样是跟新前和更新后各对应一条捕获数据. 
  346.     */ 
  347.     
  348.     
  349.     --4.3 删除操作 
  350.     
  351.     
  352.     USE CDC_TEST_DB 
  353.     GO 
  354.        
  355.     DELETE FROM  TB_CDC_USER WHERE USERID=5 
  356.     
  357.     SELECT * 
  358.     FROM dbo.TB_CDC_USER 
  359.     GO 
  360.   
  361.     SELECT * 
  362.     FROM cdc.dbo_TB_CDC_USER_CT 
  363.     GO 
  364.   
  365.     /*结果 
  366.     USERID      NAME                 ADDRESS 
  367.     ----------- -------------------- ------------------ 
  368.     1           香蕉                  dss省fdfd市 
  369.     2           鸽子                  山东省青岛市 
  370.     3           水哥                  江苏省苏州市 
  371.     4           土豆                  XX省XX市 
  372.     
  373.     (4 行受影响) 
  374.     
  375.     __$start_lsn         __$end_lsn __$seqval            __$operation  __$update_mask    USERID  NAME   ADDRESS 
  376.     ----------------------   ----------- --------------------- ------------  --------------    ------- ------    ------------ 
  377.     0x0000002C000001E30004   NULL       0x0000002C000001E30003   2             0x07          5       九零后  毛毛省毛毛市 
  378.     0x0000002D0000004D0004   NULL       0x0000002D0000004D0002   3             0x04          5       九零后  毛毛省毛毛市 
  379.     0x0000002D0000004D0004   NULL       0x0000002D0000004D0002   4             0x04          5       九零后  YY省YY市 
  380.     0x00000035000001310005   NULL       0x00000035000001310002   1             0x07          5       九零后  YY省YY市 
  381.   
  382.     和跟新后的dbo_TB_CDC_USER_CT表相比多了一条__$operation=1 的数据,代表了删除操作所捕获的数据. 
  383.     */ 
  384.     
  385. /* 
  386.   5 查询变更数据 
  387. */ 
  388.     
  389.     /*生成变更后就可以用CDC函数查看变更历史了,使用日志序列号(Log sequence number,LSN) 
  390.       跟踪数据的变更.LSN是在事务日志中唯一标志一个活动记录. 
  391.     
  392.     
  393.       使用函数sys.fn_cdc_map_time_to_lsn获取变更范围内的的最大和最小LSN值.这函数有个 
  394.       输入值关系运算符和跟踪时间(还可以用其他的方法确定LSN,下面会讲到).关系运算符有: 
  395.       smallest greater than;  smallest greater than or equal;    largest less than; 
  396.       largest less than or equal. 
  397.       
  398.     */ 
  399.     --获得对应时间内的LSN边界. 
  400.     SELECT SYS.fn_cdc_map_time_to_lsn('smallest greater than or equal','2010-05-20 14:00:00'AS BGLSN 
  401.     SELECT SYS.fn_cdc_map_time_to_lsn('largest less than or equal','2010-05-20 16:00:00'AS EDLSN 
  402.     
  403.     /* 
  404.     根据LSN边界用函数CDC.fn_cdc_get_all_changes_dbo_TB_CDC_USER获得时间段内的净变更. 
  405.     MSDN:cdc.fn_cdc_get_all_changes_<捕获实例> http://msdn.microsoft.com/zh-cn/vstudio/bb510627.aspx 
  406.     
  407.     为了防止出现指定的LSN 范围不在捕获实例的更改跟踪时间线范围之内,则函数将返回错误208(“为过程或函数 
  408.     cdc.fn_cdc_get_all_changes 提供的参数数目不足。”)。各位在测试的时候可以先通过 
  409.     sys.fn_cdc_map_lsn_to_time函数来查询一下变更的时间. 
  410.     
  411.     我在这地方郁闷了老半天 
  412.     */ 
  413.   
  414.     SELECT __$OPERATION,sys.fn_cdc_map_lsn_to_time(__$start_lsn),USERID,NAME,ADDRESS 
  415.     FROM cdc.dbo_TB_CDC_USER_CT 
  416.     
  417.     /* 
  418.     __$OPERATION                         USERID      NAME                 ADDRESS 
  419.     ------------ ----------------------- ----------- -------------------- ---------------- 
  420.     2            2010-05-20 15:43:24.920 5           九零后                 毛毛省毛毛市 
  421.     3            2010-05-20 15:49:54.203 5           九零后                 毛毛省毛毛市 
  422.     4            2010-05-20 15:49:54.203 5           九零后                 YY省YY市 
  423.     1            2010-05-20 16:16:17.280 5           九零后                 YY省YY市 
  424.   
  425.     (4 行受影响) 
  426.     */ 
  427.   
  428.     DECLARE @BGLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('smallest greater than or equal','2010-05-20 15:43:24.920')--该处的时间如果早于你CDC开启的时间会出问题 
  429.     DECLARE @EDLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('largest less than or equal','2010-05-21 16:16:17.280'
  430.     SELECT __$OPERATION 
  431.            ,__$UPDATE_MASK 
  432.            ,USERID 
  433.            ,NAME 
  434.            ,ADDRESS 
  435.     FROM   cdc.fn_cdc_get_all_changes_dbo_TB_CDC_USER(@BGLSN,@EDLSN,'all')  --all | all update old 
  436.   
  437.     /*结果 
  438.     __$OPERATION __$UPDATE_MASK USERID      NAME                 ADDRESS 
  439.     ------------ -------------- ----------- -------------------- ------------ 
  440.     2            0x07           5           九零后              毛毛省毛毛市 --为插入的数据 
  441.     4            0x04           5           九零后              YY省YY市      --数据行更新后的版本 
  442.     1            0x07           5           九零后              YY省YY市      --为删除的数据 
  443.   
  444.     (3 行受影响) 
  445.   
  446.     以上结果展示了该表发生的所有更改.大家应该能够理解cdc.fn_cdc_get_all_changes_dbo_TB_CDC_USER是根 
  447.     据你的原表进行命名的.同时查询的数据源表cdc.dbo_TB_CDC_USER_CT中的数据相比少了一条__$OPERATION为 
  448.     3的那行数据,那是因为参数ALL影响的.下面会有ALL UPDATE OLD选项的查询. 
  449.     
  450.     
  451.     也许下面的查询结果更好理解一点 
  452.     */ 
  453.     
  454.     DECLARE @BGLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('smallest greater than or equal','2010-05-20 15:43:24.920'
  455.     DECLARE @EDLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('largest less than or equal','2010-05-20 16:16:17.280'
  456.     
  457.     SELECT CASE __$OPERATION 
  458.                 WHEN 1 THEN '删除的数据' 
  459.                 WHEN 2 THEN '插入的数据' 
  460.                 WHEN 3 THEN '更新前的数据行' 
  461.                 WHEN 4 THEN '更新后的数据行' 
  462.             END AS OPERATION 
  463.            ,__$UPDATE_MASK 
  464.            ,USERID 
  465.            ,NAME 
  466.            ,ADDRESS 
  467.     FROM   cdc.fn_cdc_get_all_changes_dbo_TB_CDC_USER(@BGLSN,@EDLSN,'all update old'
  468.   
  469.     /*结果 
  470.     OPERATION         __$UPDATE_MASK   USERID      NAME  ADDRESS 
  471.     --------------       ---------------- ----------- ------- ------------- 
  472.     插入的数据         0x07         5           九零后   毛毛省毛毛市 
  473.     更新前的数据行     0x04         5           九零后   毛毛省毛毛市 
  474.     更新后的数据行     0x04         5           九零后   YY省YY市 
  475.     删除的数据         0x07         5           九零后   YY省YY市 
  476.   
  477.     (4 行受影响) 
  478.     */ 
  479.   
  480.     /* 
  481.     从CDC表查询净变更. 
  482.     在开始开启CDC的时候,执行sp_cdc_enbale_table_change_data_capture时@supports_net_changes=1 
  483.     该参数决定我们可以选择CDC净变更版本.用fn_cdc_get_net_changes_dbo_TB_CDC_USER来获得.该函 
  484.     数和cdc.fn_cdc_get_all_changes_dbo_TB_CDC_USER相似同样接收个参数.前个参数接收起始LSN 
  485.     边界值,第个不同. 
  486.        all : 返回行最后的更改,不显示更新掩码的值. 
  487.        all with mask :返回行最后的更改和掩码值. 
  488.        all with merge :返回行最终的更改,不管是删除还是合并操作(插入或者更新)插入和更新不会 
  489.                      被打断.由于用来确定给定更改的精确操作的逻辑会增加查询的复杂性,所以 
  490.                      ,在只需指出应用更改数据所需的操作是插入还是更新但不必明确区分这两 
  491.                      者时,使用该选项可提高查询性能. 
  492.     
  493.     
  494.     为了更清楚一点,下面进行一些数据修改.*/ 
  495.     
  496.     USE CDC_TEST_DB 
  497.     GO 
  498.     
  499.     INSERT TB_CDC_USER(NAME,ADDRESS) VALUES 
  500.     ('九零后','毛毛省毛毛市'
  501.     --该条记录的USERID应该是 
  502.     
  503.     UPDATE TB_CDC_USER 
  504.     SET ADDRESS='YY省YY市' 
  505.     WHERE USERID=6 
  506.     
  507.     
  508.     --查询前后的净更改 
  509.     
  510.     /*  此处说明一下下面个函数返回的__$OPERATION 
  511.        如果第三个参数的值为all 或all with mask,则此列中的值可以是以下值之一: 
  512.        1 = 删除;2 = 插入;4 = 更新 
  513.        
  514.        如果第三个参数参数的值为all with merge,则此列中的值可以是以下值之一: 
  515.        1 = 删除;5 = 插入或更新 
  516.        值为5 表示行是否已存在以及是否只需要更新是未知的,或者行当前是否存在以 
  517.        及是否必须插入是未知的。 
  518.     */ 
  519.   
  520.     DECLARE @BEGINDATE DATETIME='2010-05-20 18:50:17.280' 
  521.     DECLARE @ENDDATE DATETIME='2010-05-20 19:00:00' 
  522.     
  523.     
  524.     DECLARE @BGLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('smallest greater than or equal',@BEGINDATE) 
  525.     DECLARE @EDLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('largest less than or equal',@ENDDATE) 
  526.     
  527.     SELECT 
  528.            CASE __$OPERATION 
  529.               WHEN 1 THEN '删除' 
  530.               WHEN 2 THEN '插入' 
  531.               WHEN 4 THEN '更新' 
  532.               WHEN 5 THEN '合并' 
  533.            END AS OPERATION 
  534.            ,__$UPDATE_MASK 
  535.            ,USERID 
  536.            ,NAME 
  537.            ,ADDRESS 
  538.     FROM   CDC.FN_CDC_GET_NET_CHANGES_DBO_TB_CDC_USER(@BGLSN,@EDLSN,'all with mask'
  539.     
  540.     
  541.     /* 
  542.     OPERATION  __$UPDATE_MASK    USERID NAME        ADDRESS 
  543.     ---------- ---------------  ------ ----------- ----------- 
  544.     插入    NULL           6      九零后     YY省YY市 
  545.   
  546.     (1 行受影响) 
  547.     
  548.     上面的操作我是先插入一条数据,然后更新它,查询对应的LSN范围内净变更,虽然生成次变更 
  549.     但是只需要返回一行来反映最终的变更,即最终的INSERT操作 
  550.     */ 
  551.     
  552.     
  553.     
  554.     /*翻译CDC更新掩码 
  555.     
  556.       通过上面的个函数cdc.fn_cdc_get_net_changes_..和cdc.fn_cdc_get_net_changes_..返 
  557.       回的更新掩码可以确定哪些列被操作影响了.需要借助下面的个CDC函数. 
  558.       
  559.       sys.fn_cdc_is_bit_set检查是否在掩码中设定了指定位.它的第一个参数是要检查的位序号 
  560.       ,第二个参数是更新掩码本身. 返回值为BIT 
  561.       
  562.       将sys.fn_cdc_get_column_ordinal和sys.fn_cdc_is_bit_set一起使用来确定表列的序号位 
  563.       置,该函数第一个参数是捕获实例的名称.第二个参数是列的名称.返回值INT型列序号位置. 
  564.       
  565.      下面使用者个函数来识别在指定的LSN边界中更新了哪些列. 
  566.     */ 
  567.     
  568.   
  569.   
  570.      USE CDC_TEST_DB 
  571.      GO 
  572.       
  573.       
  574.      ---SELECT GETDATE() '2010-05-20 19:37:57.910' 
  575.      UPDATE TB_CDC_USER 
  576.      SET NAME='小草' 
  577.      WHERE USERID=1 
  578.       
  579.      UPDATE TB_CDC_USER 
  580.      SET ADDRESS='火星' 
  581.      WHERE USERID=4 
  582.       
  583.      --下面使用更新掩码来侦测哪些累发生了改变. 
  584.       
  585.      DECLARE @BEGINDATE DATETIME='2010-05-20 19:37:57.910' 
  586.      DECLARE @ENDDATE DATETIME='2010-05-20 23:59:59' 
  587.       
  588.       
  589.      DECLARE @fromLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('smallest greater than or equal',@BEGINDATE) 
  590.      DECLARE @toLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('largest less than or equal',@ENDDATE) 
  591.     
  592.       
  593.      SELECT 
  594.            sys.fn_cdc_is_bit_set( 
  595.            --该函数的第一个参数是希望检测的列的序号位置.为了返回序号 
  596.            --调用如下函数 
  597.                   sys.fn_cdc_get_column_ordinal( 
  598.                      'DBO_TB_CDC_USER','NAME'
  599.            --第二个参数是更新掩码本身,调用更更新掩码列. 
  600.                      ,__$update_mask) NAME_UPDATED, 
  601.            sys.fn_cdc_is_bit_set( 
  602.                   sys.fn_cdc_get_column_ordinal( 
  603.                      'DBO_TB_CDC_USER','ADDRESS'
  604.                      ,__$update_mask) ADDRESS_UPDATED 
  605.            ,USERID 
  606.            ,NAME 
  607.            ,ADDRESS 
  608.      FROM  CDC.FN_CDC_GET_ALL_CHANGES_DBO_TB_CDC_USER(@fromLSN,@toLSN,'all'
  609.      --限定返回类型为的行,它是更新操作之后的行 
  610.      WHERE __$OPERATION= 4 
  611.     
  612.     
  613.     /*结果 
  614.     
  615.     NAME_UPDATED ADDRESS_UPDATED USERID      NAME                 ADDRESS 
  616.     ------------ --------------- ----------- -------------------- -------------- 
  617.     1            0               1           小草                  dss省fdfd市 
  618.     0            1               4           土豆                  火星 
  619.   
  620.     (2 行受影响) 
  621.     
  622.     
  623.     结果中一个更新了NAME,一个更新了ADDRESS. 
  624.     */ 
  625.     
  626. /* 
  627.   6 使用LSN边界 
  628.   
  629.   可以使用sys.fn_cdn_map_time_to_lsn来确定最大最小LSN边界.以下的几个函数都可以用来产生 
  630.   LSN值. 
  631.        sys.fn_cdc_incremnet_lsn 返回基于输入的LSN的下一个LSN值. 
  632.        sys.fn_cdc_decrement_lsn 看名字可以知道应该是返回输入的LSN之前的LSN值. 
  633.        sys.fn_cdc_get_max_lsn 在捕获实例收集的CDC数据中返回最大的LSN. 
  634.        sys.fn_cdc_get_min_lsn 在捕获实例收集的CDC数据中返回最小的LSN. 
  635. */     
  636.        
  637.        select sys.fn_cdc_get_max_lsn() as max_lsn --返回数据库级别的最大LSN 
  638.        select sys.fn_cdc_get_min_lsn('dbo_tb_cdc_user'as min_lsn--需要捕获实例名称做参数 
  639.        select sys.fn_cdc_increment_lsn(sys.fn_cdc_get_max_lsn()) -- 新的下界LSN 
  640.        select sys.fn_cdc_decrement_lsn(sys.fn_cdc_get_max_lsn()) -- 新的下界LSN之前的LSN 
  641.        /*结果 
  642.               max_lsn 
  643.        ---------------------- 
  644.        0x0000003B0000016F0001 
  645.   
  646.        (1 行受影响) 
  647.   
  648.        min_lsn 
  649.        ---------------------- 
  650.        0x00000029000000A9003F 
  651.   
  652.        (1 行受影响) 
  653.   
  654.   
  655.        ---------------------- 
  656.        0x0000003B0000016F0002 
  657.   
  658.        (1 行受影响) 
  659.   
  660.   
  661.        ---------------------- 
  662.        0x0000003B0000016F0000 
  663.   
  664.        (1 行受影响) 
  665.        */ 
  666.   
  667. /* 
  668.   禁用表和数据的变更数据捕获 
  669.   
  670.        
  671.          禁用表数据捕获. 
  672.          sys.sp_cdc_disable_table 
  673.          [ @source_schema = ] 'source_schema' , --架构名称 
  674.          [ @source_name = ] 'source_name'       --表名称 
  675.          [ , [ @capture_instance = ] 'capture_instance' | 'all' ] --开始启用CDC时写入参数 
  676.          
  677.          
  678.          禁用数据CDC,执行如下过程后将从数据库完整删除CDC功能.相关架构和作业一并删除 
  679.          sys.sp_cdc_disable_db 
  680.   
  681.          
  682. */         
  683.          exec sys.sp_cdc_disable_table 'dbo','TB_CDC_USER','ALL' ---禁用表变更数据捕获 
  684.        
  685.          SELECT IS_TRACKED_BY_CDC FROM SYS.TABLES 
  686.          WHERE NAME ='TB_CDC_USER'  AND SCHEMA_ID=SCHEMA_ID('DBO'
  687.        
  688.          /* 
  689.            IS_TRACKED_BY_CDC 
  690.            ----------------- 
  691.            0 
  692.   
  693.            (1 行受影响) 
  • 下一篇资讯: 推荐十大企业级数据库
  • 设为首页 | 加入收藏 | 网学首页 | 原创论文 | 计算机原创
    版权所有 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2020 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号 常年法律顾问:王律师