程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> SQL SERVER 2008 數據變更捕獲(CDC )

SQL SERVER 2008 數據變更捕獲(CDC )

編輯:關於SqlServer

寫的不對的地方請各位指正,寫的也比較亂。講究這看吧。^ ^

/*

SQL Server 2008 異步捕獲表數據修改

 

 

SQL Server 2008為異步跟蹤所有發生在用戶表上的數據修改提供了內建的方法,

而不需要編寫自定義的觸發器或者查詢,變更數據捕獲擁有最小性能開銷,可以

用於其它數據源的持續更新,例如,將OLTP數據庫中的數據變更遷移到數據倉庫

數據庫.下面我們演示該功能.

 

 

*/

 

 

/*

  1 建立測試數據庫

*/

IF NOT EXISTS (SELECT NAME FROM SYS.databases WHERE name='CDC_TEST_DB')

 

BEGIN

    CREATE DATABASE CDC_TEST_DB

END

 

/*

  2 在把CDC增加到CDC_TEST_DB數據庫的表中,首先應該驗證數據庫是否啟用了數據

    捕獲

*/

 

    --驗證是否開啟

    SELECT IS_CDC_ENABLED FROM SYS.databases WHERE name='CDC_TEST_DB'

    /*

    IS_CDC_ENABLED

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

    0

 

    (1 行受影響)

    */

 

    --啟用數據變更,在CDC_TEST_DB數據庫中執行SYS.SP_CDC_ENABLE_DB存儲過程:

 

    USE CDC_TEST_DB

    GO

 

    EXEC sys.SP_CDC_ENABLE_DB

    GO

 

    /*

      CDC_TEST_DB開啟數據捕獲後,你將會在CDC_TEST_DB->安全性->架構下面看到新

      建立了一個CDC架構.

 

      同樣在CDC_TEST_DB會建立一些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函數.

 

    */

 

    --下面再驗證看看是否已經開啟數據庫開啟

    SELECT IS_CDC_ENABLED FROM SYS.databases WHERE name='CDC_TEST_DB'

 

    /*

    IS_CDC_ENABLED

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

    1

 

    (1 行受影響)

    */

 

/*

  3 開啟數據捕獲之後,可以在數據庫中通過使用SYS.SP_CDC_ENABLE_TABLE系統SP對表進行

     變更捕獲.SP描述如下

       sys.sp_cdc_enable_table

       [ @source_schema = ] 'source_schema',

       [ @source_name = ] 'source_name' ,

       [ @role_name = ] 'role_name'

       [,[ @capture_instance = ] 'capture_instance' ]

       [,[ @supports_net_changes = ] supports_net_changes ]

       [,[ @index_name = ] 'index_name' ]

       [,[ @captured_column_list = ] 'captured_column_list' ]

       [,[ @filegroup_name = ] 'filegroup_name' ]

       [,[ @allow_partition_switch = ] 'partition_switch' ]

 

    @source_schema :

    是源表所屬的架構的名稱.source_schema 的數據類型為sysname,無默認值,並且

    不能為NULL.

 

    @source_name :

    是對其啟用變更數據捕獲的源表的名稱.source_name 的數據類型為sysname,無默

    認值,並且不能為NULL.   source_name 必須存在於當前數據庫中.不能對cdc 架構

    中的表啟用變更數據捕獲.

 

    @role_name :

    是用於控制更改數據訪問的數據庫角色的名稱.role_name 為sysname,並且必須指定.

    如果顯式設置為NULL,則沒有控制角色用於限制對更改數據的訪問.如果當前存在該角

    色,則使用它.如果不存在該角色,則會嘗試創建具有指定名稱的數據庫角色.在嘗試創

    建該角色之前,將刪除角色名稱字符串右側的空格.如果調用方無權在數據庫中創建角色,

    則存儲過程操作將失敗.

 

    @capture_instance :

    是用於命名特定於實例的變更數據捕獲對象的捕獲實例的名稱.capture_instance 為

    sysname,並且不能為NULL.源表最多可以有兩個捕獲實例.

 

    @supports_net_changes :

    指示是否對此捕獲實例啟用淨更改查詢支持.supports_net_changes 為bit,如果此表有

    主鍵,或者有已使用@index_name 參數進行標識的唯一索引,則此參數的默認值為1.否

    則,此參數默認為0.如果為0,則只生成查詢所有更改的支持函數.如果為1,則還會生成查詢淨更改所需的函數.

 

    如果將supports_net_changes 設置為1,則必須指定index_name,或者源表必須具有已

    定義的主鍵.

 

    @index_name :

    用於唯一標識源表中的行的唯一索引的名稱.index_name 為sysname,並且可以為NULL.如

    果指定,則index_name 必須是源表的唯一有效索引.如果指定index_name,則標識的索引列

    優先於任何定義的主鍵列,就像表的唯一行標識符一樣. 

 

    @captured_column_list :

    標識將包括在更改表中的源表列.captured_column_list 的數據類型為nvarchar(max),並且

    可以為NULL.如果為NULL,則所有列都將包括在更改表中.

 

    @filegroup_name : 這個選項允許指定CDC的數據存儲到哪裡.filegroup_name 為sysname,並且

    可以NULL.如果指定   ,則必須為當前數據庫定義filegroup_name.如果為NULL,則使用默認文

    件組.   對於大型數據集,通過不同的文件組進行分隔會帶來更好的管理型和性能.

 

    @allow_partition_switch : 指示是否可以對啟用了變更數據捕獲的表執行ALTER TABLE 的SWITCH

    PARTITION 命令.allow_partition_switch 為bit,默認值為1.

 

 

*/

 

 

    --創建測試表

 

    CREATE TABLE TB_CDC_USER(

       USERID  INT NOT NULL PRIMARY KEY  IDENTITY(1,1)

       ,NAME VARCHAR(20) NOT NULL

       ,ADDRESS  VARCHAR(100) NOT NULL)

 

 

    INSERT TB_CDC_USER(NAME,ADDRESS) VALUES

    ('香蕉','dss省fdfd市'),

    ('鴿子','山東省青島市'),

    ('水哥','江蘇省蘇州市'),

    ('土豆','XX省XX市');

 

 

    --捕獲所有行發生的變更,只返回行的淨變更.其它為默認值

 

    EXEC sys.sp_cdc_enable_table

       @source_schema ='dbo'

       ,@source_name='TB_CDC_USER'

       ,@role_name=null

       ,@capture_instance=null

       ,@supports_net_changes=1

       ,@index_name=null

       ,@captured_column_list=null

       ,@filegroup_name=default

       ,@allow_partition_switch=1

/*    

    執行後會啟動個作業,每個啟用表CDC的都會啟用以下個作業.

    如果已經存在啟用了CDC的表,則作業不會被重建

 

       cdc.CDC_TEST_DB_capture  捕獲作業

           該作業的職責是使用日志讀取器技術捕獲發生的變更,並且在

           SQLSERVER啟動並運行時設定為自動運行.當JOB運行的時候會

           調用系統SP sys.sp_MScdc_capture_job,該sp內部調用調用

           sys.sp_cdc_scan.如果變更數據捕獲日志掃描操作已經處於

           活動狀態,或數據庫啟用了事務復制,則無法顯式執行此過程.

           此存儲過程應當由需要自定義自動配置的捕獲作業的行為的管

           理員使用.

 

 

       cdc.CDC_TEST_DB_cleanup  清除作業

           默認為每天上午點運行,默認是清除存放天以上的數據.

           調用系統存儲過程sys.sp_MScdc_cleanup_job

 

 

    執行成功之後同樣在CDC_TEST_DB數據庫系統表中會生成表cdc.dbo_TB_CDC_USER_CT,

    該表包含TB_CDC_USER_CT表上所有的變更.展開表後會發現新增加了列.

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

       __$end_lsn

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

       __$Operation 識與相應更改關聯的數據操作語言(DML) 操作.可以是下列值之一:

                     1 = 刪除;2 = 插入;3 = 更新(舊值)列數據中具有執行更新語句之

                     前的行值.4 = 更新(新值)列數據中具有執行更新語句之後的行值.

 

 

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

 

    其中很重要的列__$Operation and __$update_mask

 

*/

 

 

/*

    通過下面的查詢確認這個表已經被跟蹤

*/ 

    SELECT is_tracked_by_cdc

    FROM SYS.TABLES

    WHERE NAME='TB_CDC_USER'

         AND SCHEMA_ID=SCHEMA_ID('DBO')

/*   

    is_tracked_by_cdc

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

    1

 

    (1 行受影響)

*/

 

 

/*也可以使用sys.sp_cdc_help_change_data_capture來驗證數據捕獲的配置.

       sys.sp_cdc_help_change_data_capture

         [ [ @source_schema = ] 'source_schema' ]--表的架構名

         [, [ @source_name = ] 'source_name' ]      --表名稱

*/

 

    EXEC sys.sp_cdc_help_change_data_capture 'DBO','TB_CDC_USER'

/* 

    查詢結果:

    source_schema            dbo

    source_table             TB_CDC_USER

    capture_instance         dbo_TB_CDC_USER

    object_id                373576369

    source_object_id start_lsn  309576141

    end_lsn                     0x0000001A000001CE003B

    supports_net_changes     NULL

    has_drop_pending         1

    role_name                NULL

    index_name               NULL

    filegroup_name              PK__TB_CDC_U__7B9E7F35145C0A3F

    create_date                 2010-05-20 11:48:58.177

    index_column_list        [USERID]

    captured_column_list     [USERID], [NAME], [ADDRESS]

*/

 

 

 

/*

  4 進行變更捕獲測試.

 

     先查看那表中都寫什麼數據.

*/

 

       USE CDC_TEST_DB

       GO

       SELECT *

       FROM dbo.TB_CDC_USER

       GO

 

       SELECT *

       FROM cdc.dbo_TB_CDC_USER_CT

       GO

 

       /*結果

       USERID      NAME                 ADDRESS

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

       1           香蕉                  dss省fdfd市

       2           鴿子                  山東省青島市

       3           水哥                  江蘇省蘇州市

       4           土豆                  XX省XX市

 

       (4 行受影響)

 

       __$start_lsn  __$end_lsn   __$seqval __$Operation __$update_mask USERID  NAME  ADDRESS

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

 

       (0 行受影響)

       */

 

 

    --  4.1 插入操作

 

    USE CDC_TEST_DB

    GO

 

    INSERT TB_CDC_USER(NAME,ADDRESS) VALUES

    ('九零後','毛毛省毛毛市')

 

 

    SELECT *

    FROM dbo.TB_CDC_USER

    GO

 

    SELECT *

    FROM cdc.dbo_TB_CDC_USER_CT

    GO

    /*

    USERID      NAME                 ADDRESS

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

    1           香蕉                  dss省fdfd市

    2           鴿子                  山東省青島市

    3           水哥                  江蘇省蘇州市

    4           土豆                  XX省XX市

    5           九零後                 毛毛省毛毛市

    (5 行受影響)

 

    __$start_lsn         __$end_lsn __$seqval            __$Operation  __$update_mask    USERID  NAME   ADDRESS

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

    0x0000002C000001E30004   NULL       0x0000002C000001E30003   2             0x07          5       九零後  毛毛省毛毛市

 

    (1 行受影響)

 

    上面的結果中看出當TB_CDC_USER插入一條數據後,同樣在跟蹤表中可以有一條相同的數據_Operation

    值為代表這是一條插入操作.

    */

 

 

    --4.2更新操作

 

    USE CDC_TEST_DB

    GO

 

    UPDATE TB_CDC_USER

    SET ADDRESS='YY省YY市'

    WHERE USERID=5

 

    SELECT *

    FROM dbo.TB_CDC_USER

    GO

 

    SELECT *

    FROM cdc.dbo_TB_CDC_USER_CT

    GO

 

    /*結果

    USERID      NAME                 ADDRESS

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

    1           香蕉                  dss省fdfd市

    2           鴿子                  山東省青島市

    3           水哥                  江蘇省蘇州市

    4           土豆                  XX省XX市

    5           九零後                 YY省YY市

 

    (5 行受影響)

 

    __$start_lsn         __$end_lsn __$seqval            __$Operation  __$update_mask    USERID  NAME   ADDRESS

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

    0x0000002C000001E30004   NULL       0x0000002C000001E30003   2             0x07          5       九零後  毛毛省毛毛市

    0x0000002D0000004D0004   NULL       0x0000002D0000004D0002   3             0x04          5       九零後  毛毛省毛毛市

    0x0000002D0000004D0004   NULL       0x0000002D0000004D0002   4             0x04          5       九零後  YY省YY市

 

 

    同樣我們查詢dbo_TB_CDC_USER_CT後會發現比之前多了條數據,分別為USERID=6這條數據更新

    前和更新後的數據,__$Operation為代表UPDATE前的數據,4為UPDATE後的數據.如果是多列數據

    一起更新同樣是跟新前和更新後各對應一條捕獲數據.

    */

 

 

    --4.3 刪除操作

 

 

    USE CDC_TEST_DB

    GO

 

    DELETE FROM  TB_CDC_USER WHERE USERID=5

 

    SELECT *

    FROM dbo.TB_CDC_USER

    GO

 

    SELECT *

    FROM cdc.dbo_TB_CDC_USER_CT

    GO

 

    /*結果

    USERID      NAME                 ADDRESS

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

    1           香蕉                  dss省fdfd市

    2           鴿子                  山東省青島市

    3           水哥                  江蘇省蘇州市

    4           土豆                  XX省XX市

    (4 行受影響)

 

    __$start_lsn         __$end_lsn __$seqval            __$Operation  __$update_mask    USERID  NAME   ADDRESS

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

    0x0000002C000001E30004   NULL       0x0000002C000001E30003   2             0x07          5       九零後  毛毛省毛毛市

    0x0000002D0000004D0004   NULL       0x0000002D0000004D0002   3             0x04          5       九零後  毛毛省毛毛市

    0x0000002D0000004D0004   NULL       0x0000002D0000004D0002   4             0x04          5       九零後  YY省YY市

    0x00000035000001310005   NULL       0x00000035000001310002   1             0x07          5       九零後  YY省YY市

 

    和跟新後的dbo_TB_CDC_USER_CT表相比多了一條__$Operation=1 的數據,代表了刪除操作所捕獲的數據.

    */

 

/*

  5 查詢變更數據

*/

 

    /*生成變更後就可以用CDC函數查看變更歷史了,使用日志序列號(Log sequence number,LSN)

      跟蹤數據的變更.LSN是在事務日志中唯一標志一個活動記錄.

 

 

      使用函數sys.fn_cdc_map_time_to_lsn獲取變更范圍內的的最大和最小LSN值.這函數有個

      輸入值關系運算符和跟蹤時間(還可以用其他的方法確定LSN,下面會講到).關系運算符有:

      smallest greater than;  smallest greater than or equal;    largest less than;

      largest less than or equal.

 

    */

    --獲得對應時間內的LSN邊界.

    SELECT SYS.fn_cdc_map_time_to_lsn('smallest greater than or equal','2010-05-20 14:00:00') AS BGLSN

    SELECT SYS.fn_cdc_map_time_to_lsn('largest less than or equal','2010-05-20 16:00:00') AS EDLSN

 

    /*

    根據LSN邊界用函數CDC.fn_cdc_get_all_changes_dbo_TB_CDC_USER獲得時間段內的淨變更.

    MSDN:cdc.fn_cdc_get_all_changes_<捕獲實例> http://msdn.microsoft.com/zh-cn/vstudio/bb510627.ASPx

 

    為了防止出現指定的LSN 范圍不在捕獲實例的更改跟蹤時間線范圍之內,則函數將返回錯誤208(“為過程或函數

    cdc.fn_cdc_get_all_changes 提供的參數數目不足。”)。各位在測試的時候可以先通過

    sys.fn_cdc_map_lsn_to_time函數來查詢一下變更的時間.

 

    我在這地方郁悶了老半天

    */

 

    SELECT __$OperaTION,sys.fn_cdc_map_lsn_to_time(__$start_lsn),USERID,NAME,ADDRESS

    FROM cdc.dbo_TB_CDC_USER_CT

 

    /*

    __$OperaTION                         USERID      NAME                 ADDRESS

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

    2            2010-05-20 15:43:24.920 5           九零後                 毛毛省毛毛市

    3            2010-05-20 15:49:54.203 5           九零後                 毛毛省毛毛市

    4            2010-05-20 15:49:54.203 5           九零後                 YY省YY市

    1            2010-05-20 16:16:17.280 5           九零後                 YY省YY市

 

    (4 行受影響)

    */

 

    DECLARE @BGLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('smallest greater than or equal','2010-05-20 15:43:24.920')--該處的時間如果早於你CDC開啟的時間會出問題

    DECLARE @EDLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('largest less than or equal','2010-05-21 16:16:17.280')

    SELECT __$OperaTION

           ,__$UPDATE_MASK

           ,USERID

           ,NAME

           ,ADDRESS

    FROM   cdc.fn_cdc_get_all_changes_dbo_TB_CDC_USER(@BGLSN,@EDLSN,'all')  --all | all update old

 

    /*結果

    __$OperaTION __$UPDATE_MASK USERID      NAME                 ADDRESS------------ -------------- ----------- -------------------- ------------

    2            0x07           5           九零後              毛毛省毛毛市 --為插入的數據

    4            0x04           5           九零後              YY省YY市      --數據行更新後的版本

    1            0x07           5           九零後              YY省YY市      --為刪除的數據

 

    (3 行受影響)

 

    以上結果展示了該表發生的所有更改.大家應該能夠理解cdc.fn_cdc_get_all_changes_dbo_TB_CDC_USER是根

    據你的原表進行命名的.同時查詢的數據源表cdc.dbo_TB_CDC_USER_CT中的數據相比少了一條__$OperaTION為

    3的那行數據,那是因為參數ALL影響的.下面會有ALL UPDATE OLD選項的查詢.

 

 

    也許下面的查詢結果更好理解一點

    */

 

    DECLARE @BGLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('smallest greater than or equal','2010-05-20 15:43:24.920')

    DECLARE @EDLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('largest less than or equal','2010-05-20 16:16:17.280')

 

    SELECT CASE __$OperaTION

                WHEN 1 THEN '刪除的數據'

                WHEN 2 THEN '插入的數據'

                WHEN 3 THEN '更新前的數據行'

                WHEN 4 THEN '更新後的數據行'

            END AS OperaTION

           ,__$UPDATE_MASK

           ,USERID

           ,NAME

           ,ADDRESS

    FROM   cdc.fn_cdc_get_all_changes_dbo_TB_CDC_USER(@BGLSN,@EDLSN,'all update old')

 

    /*結果

    OperaTION         __$UPDATE_MASK   USERID      NAME  ADDRESS

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

    插入的數據         0x07         5           九零後   毛毛省毛毛市

    更新前的數據行     0x04         5           九零後   毛毛省毛毛市

    更新後的數據行     0x04         5           九零後   YY省YY市

    刪除的數據         0x07         5           九零後   YY省YY市

 

    (4 行受影響)

    */

 

    /*

    從CDC表查詢淨變更.

    在開始開啟CDC的時候,執行sp_cdc_enbale_table_change_data_capture時@supports_net_changes=1

    該參數決定我們可以選擇CDC淨變更版本.用fn_cdc_get_net_changes_dbo_TB_CDC_USER來獲得.該函

    數和cdc.fn_cdc_get_all_changes_dbo_TB_CDC_USER相似同樣接收個參數.前個參數接收起始LSN

    邊界值,第個不同.

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

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

       all with merge :返回行最終的更改,不管是刪除還是合並操作(插入或者更新)插入和更新不會

                     被打斷.由於用來確定給定更改的精確操作的邏輯會增加查詢的復雜性,所以

                     ,在只需指出應用更改數據所需的操作是插入還是更新但不必明確區分這兩

                     者時,使用該選項可提高查詢性能.

 

 

    為了更清楚一點,下面進行一些數據修改.*/

 

    USE CDC_TEST_DB

    GO

 

    INSERT TB_CDC_USER(NAME,ADDRESS) VALUES

    ('九零後','毛毛省毛毛市')

    --該條記錄的USERID應該是

 

    UPDATE TB_CDC_USER

    SET ADDRESS='YY省YY市'

    WHERE USERID=6

 

 

    --查詢前後的淨更改

 

    /*  此處說明一下下面個函數返回的__$OperaTION

       如果第三個參數的值為all 或all with mask,則此列中的值可以是以下值之一:

       1 = 刪除;2 = 插入;4 = 更新

       如果第三個參數參數的值為all with merge,則此列中的值可以是以下值之一:

       1 = 刪除;5 = 插入或更新

       值為5 表示行是否已存在以及是否只需要更新是未知的,或者行當前是否存在以

       及是否必須插入是未知的。

    */

 

    DECLARE @BEGINDATE DATETIME='2010-05-20 18:50:17.280'

    DECLARE @ENDDATE DATETIME='2010-05-20 19:00:00'

 

 

    DECLARE @BGLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('smallest greater than or equal',@BEGINDATE)

    DECLARE @EDLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('largest less than or equal',@ENDDATE)

 

    SELECT

           CASE __$OperaTION

              WHEN 1 THEN '刪除'

              WHEN 2 THEN '插入'

              WHEN 4 THEN '更新'

              WHEN 5 THEN '合並'

           END AS OperaTION

           ,__$UPDATE_MASK

           ,USERID

           ,NAME

           ,ADDRESS

    FROM   CDC.FN_CDC_GET_NET_CHANGES_DBO_TB_CDC_USER(@BGLSN,@EDLSN,'all with mask')

 

 

    /*

    OperaTION  __$UPDATE_MASK    USERID NAME        ADDRESS

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

    插入    NULL           6      九零後     YY省YY市

 

    (1 行受影響)

 

    上面的操作我是先插入一條數據,然後更新它,查詢對應的LSN范圍內淨變更,雖然生成次變更

    但是只需要返回一行來反映最終的變更,即最終的INSERT操作

    */

 

 

 

    /*翻譯CDC更新掩碼

 

      通過上面的個函數cdc.fn_cdc_get_net_changes_..和cdc.fn_cdc_get_net_changes_..返

      回的更新掩碼可以確定哪些列被操作影響了.需要借助下面的個CDC函數.

 

      sys.fn_cdc_is_bit_set檢查是否在掩碼中設定了指定位.它的第一個參數是要檢查的位序號

      ,第二個參數是更新掩碼本身. 返回值為BIT

 

      將sys.fn_cdc_get_column_ordinal和sys.fn_cdc_is_bit_set一起使用來確定表列的序號位

      置,該函數第一個參數是捕獲實例的名稱.第二個參數是列的名稱.返回值INT型列序號位置.

 

     下面使用者個函數來識別在指定的LSN邊界中更新了哪些列.

    */

 

 

 

     USE CDC_TEST_DB

     GO

 

 

     ---SELECT GETDATE() '2010-05-20 19:37:57.910'

     UPDATE TB_CDC_USER

     SET NAME='小草'

     WHERE USERID=1

 

     UPDATE TB_CDC_USER

     SET ADDRESS='火星'

     WHERE USERID=4

 

     --下面使用更新掩碼來偵測哪些累發生了改變.

 

     DECLARE @BEGINDATE DATETIME='2010-05-20 19:37:57.910'

     DECLARE @ENDDATE DATETIME='2010-05-20 23:59:59'

 

 

     DECLARE @fromLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('smallest greater than or equal',@BEGINDATE)

     DECLARE @toLSN VARBINARY(10)=SYS.fn_cdc_map_time_to_lsn('largest less than or equal',@ENDDATE)

 

 

     SELECT

           sys.fn_cdc_is_bit_set(

           --該函數的第一個參數是希望檢測的列的序號位置.為了返回序號

           --調用如下函數

                  sys.fn_cdc_get_column_ordinal(

                     'DBO_TB_CDC_USER','NAME')

           --第二個參數是更新掩碼本身,調用更更新掩碼列.

                     ,__$update_mask) NAME_UPDATED,

           sys.fn_cdc_is_bit_set(

                  sys.fn_cdc_get_column_ordinal(

                     'DBO_TB_CDC_USER','ADDRESS')

                     ,__$update_mask) ADDRESS_UPDATED

           ,USERID

           ,NAME

           ,ADDRESS

     FROM  CDC.FN_CDC_GET_ALL_CHANGES_DBO_TB_CDC_USER(@fromLSN,@toLSN,'all')

     --限定返回類型為的行,它是更新操作之後的行

     WHERE __$OperaTION= 4

 

 

    /*結果

 

    NAME_UPDATED ADDRESS_UPDATED USERID      NAME                 ADDRESS

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

    1            0               1           小草                  dss省fdfd市

    0            1               4           土豆                  火星

 

    (2 行受影響)

 

 

    結果中一個更新了NAME,一個更新了ADDRESS.

    */

 

/*

  6 使用LSN邊界

 

  可以使用sys.fn_cdn_map_time_to_lsn來確定最大最小LSN邊界.以下的幾個函數都可以用來產生

  LSN值.

       sys.fn_cdc_incremnet_lsn 返回基於輸入的LSN的下一個LSN值.

       sys.fn_cdc_decrement_lsn 看名字可以知道應該是返回輸入的LSN之前的LSN值.

       sys.fn_cdc_get_max_lsn 在捕獲實例收集的CDC數據中返回最大的LSN.

       sys.fn_cdc_get_min_lsn 在捕獲實例收集的CDC數據中返回最小的LSN.

*/    

 

       select sys.fn_cdc_get_max_lsn() as max_lsn --返回數據庫級別的最大LSN

       select sys.fn_cdc_get_min_lsn('dbo_tb_cdc_user') as min_lsn--需要捕獲實例名稱做參數

       select sys.fn_cdc_increment_lsn(sys.fn_cdc_get_max_lsn()) -- 新的下界LSN

       select sys.fn_cdc_decrement_lsn(sys.fn_cdc_get_max_lsn()) -- 新的下界LSN之前的LSN

       /*結果

              max_lsn

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

       0x0000003B0000016F0001

 

       (1 行受影響)

 

       min_lsn

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

       0x00000029000000A9003F

 

       (1 行受影響)

 

 

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

       0x0000003B0000016F0002

 

       (1 行受影響)

 

 

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

       0x0000003B0000016F0000

 

       (1 行受影響)

       */

 

/*

  禁用表和數據的變更數據捕獲

 

 

         禁用表數據捕獲.

         sys.sp_cdc_disable_table

         [ @source_schema = ] 'source_schema' , --架構名稱

         [ @source_name = ] 'source_name'       --表名稱

         [ , [ @capture_instance = ] 'capture_instance' | 'all' ] --開始啟用CDC時寫入參數

 

 

         禁用數據CDC,執行如下過程後將從數據庫完整刪除CDC功能.相關架構和作業一並刪除

         sys.sp_cdc_disable_db

 

 

*/        

         exec sys.sp_cdc_disable_table 'dbo','TB_CDC_USER','ALL' ---禁用表變更數據捕獲

 

         SELECT IS_TRACKED_BY_CDC FROM SYS.TABLES

         WHERE NAME ='TB_CDC_USER'  AND SCHEMA_ID=SCHEMA_ID('DBO')

 

         /*

           IS_TRACKED_BY_CDC

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

           0

 

           (1 行受影響)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved