ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 查看被CDC追踪的表的历史变更记录

查看被CDC追踪的表的历史变更记录

原创 Linux操作系统 作者:hwtong 时间:2011-11-15 15:27:28 0 删除 编辑
SET QUOTED_IDENTIFIER ON
SET ANSI_NULLS ON
GO
ALTER         PROCEDURE [dbo].[SP_Get_History] @Table_Name VARCHAR(20),@Monitor_Start_Time DATETIME ,@Monitor_End_Time DATETIME,@DML_Operation_Type VARCHAR(20)
AS
DECLARE
                 @_Tablename VARCHAR(20),
                 @_Tablename_CT VARCHAR(30),
                 @_ColList        VARCHAR(4000),
                 @_Sql VARCHAR(4000),
                 @_Sql1 VARCHAR(4000),------Create the temporary table and define the operation type
                 @_Sql2 VARCHAR(4000),
                 @_Sql3 VARCHAR(4000),------define the where condition
                 @_Sql4 VARCHAR(4000),------define the description of update
                 @_Cdcfntable VARCHAR(50),
                 @_Starttime DATETIME,
                 @_Endtime DATETIME,
                 @_SortNo INT,
                 @_MaxColID INT,
                 @_Columnname VARCHAR(20)
                 
IF NOT EXISTS(SELECT 1 FROM  sys.objects WHERE NAME=@Table_Name AND Type='U')
        BEGIN
                RAISERROR('%s',16,1,'The table does not exists in the database')
                RETURN
        END
       
IF NOT EXISTS(SELECT 1 FROM sys.tables WHERE NAME=@Table_Name AND is_tracked_by_cdc=1)
        BEGIN
                RAISERROR('%s',16,1,'There is no history log for the table')
                RETURN
        END

IF @DML_Operation_Type NOT IN ('INSERT','UPDATE','DELETE','','DELETE,INSERT','INSERT,DELETE','UPDATE,INSERT','INSERT,UPDATE','UPDATE,DELETE','DELETE,UPDATE')
        BEGIN
                RAISERROR('%s',16,1,'The DML_Operation_Type is not a valid Operation type')
                RETURN
        END
        SET @_Sql4=''
        set @_Tablename='dbo_'+@Table_name       
        SET @_Tablename_CT=@_Tablename+'_CT'
        SET @_Cdcfntable='cdc.fn_cdc_get_all_changes_'+@_Tablename
        SET @_Starttime=@Monitor_Start_Time
        SET @_Endtime=CASE @Monitor_End_Time WHEN '' THEN GETDATE() ELSE @Monitor_End_Time END
        SELECT @_ColList=''
        SELECT @_ColList = @_ColList +'['+ [column_name] + '], '  FROM cdc.captured_columns  -- Target database columns list
           WHERE        [object_id] = OBJECT_ID('cdc.' + @_Tablename_CT)  
           ORDER BY Column_id
    SET @_ColList =   LEFT(@_ColList, LEN(@_ColList) - 1)

        CREATE TABLE #CDC_Capture_Column (Source_Schema CHAR(3),Source_Table VARCHAR(50),Capture_Instance VARCHAR(50),Column_Name VARCHAR(20),Column_ID INT,Column_Ordinal INT,Data_Type VARCHAR(20),Character_Maximum_Length INT,Numeric_Precision INT,Numeric_Precision_Radix INT,Numeric_Scale INT,Datetime_Precision VARCHAR(10))

        INSERT #CDC_Capture_Column EXEC sys.sp_cdc_get_captured_columns    @Capture_Instance = @_Tablename
        SELECT        @_SortNo = 1
        FROM        #CDC_Capture_Column
       
        SELECT @_MaxColID=MAX(column_id) FROM #CDC_Capture_Column
       
       
        WHILE @_SortNo <= @_MaxColID
        BEGIN
                SELECT        @_Columnname = Column_name
                FROM        #CDC_Capture_Column
                WHERE        Column_id = @_SortNo
               
       
                set @_Sql2=
                N'
                               
                        CASE WHEN __$Operation = 4 AND 1 = sys.fn_cdc_has_column_changed (''@Tablename@'' , ''@Column_Name@'' , __$Update_Mask)
                                THEN ''@Column_Name@ Change From ''
                                                + CONVERT(NVARCHAR(1000), (SELECT @Column_Name@ FROM #AA b WHERE a.__$seqval =B.[__$seqval]   AND b.__$Operation = 3))
                                                + '' to ''
                                                + CONVERT(NVARCHAR(1000), (SELECT @Column_Name@ FROM #AA b WHERE a.__$seqval =B.[__$seqval]   AND b.__$Operation = 4))
                                                + '';''
                                ELSE ''''
                                END
                       
                       
                '
               
                SET @_SortNo = @_SortNo + 1
                SET        @_Sql2 = REPLACE(@_Sql2, '@Tablename@', @_Tablename)
                SET        @_Sql2 = REPLACE(@_Sql2, '@Column_Name@', @_Columnname)
                SET @_Sql4 = @_Sql4+'+'+ @_Sql2
               
        END
       
        set @_Sql1=
        N'   
        DECLARE @From_Lsn BINARY(10),
                         @To_Lsn BINARY(10)
        SET @From_Lsn = sys.fn_cdc_get_min_lsn(''@Tablename@'')
        SET @To_Lsn = sys.fn_cdc_get_max_lsn()
        SELECT * INTO #AA FROM @Cdcfntable@(@From_Lsn, @To_Lsn, N''all update old'')

        SELECT  sys.fn_cdc_map_lsn_to_time(a.__$Start_lsn) AS DATA_CHANGE_TIME,
                        CASE __$Operation
                                WHEN 1 THEN ''DELETE''
                                WHEN 2 THEN ''INSERT''
                                WHEN 4 THEN ''UPDATE''
                                ELSE NULL
                        END AS DML_OPERATION_TYPE,[DESCRIPTION]=
        '
        SELECT @_Sql3=
        N'
        ,@ColList@
        FROM   #AA AS a
        where sys.fn_cdc_map_lsn_to_time(a.__$Start_Lsn) >''@Starttime@'' and sys.fn_cdc_map_lsn_to_time(a.__$Start_Lsn)<''@Endtime@''
        '
        SET @_Sql=@_Sql1+@_Sql4 +@_Sql3
        SET        @_Sql = REPLACE(@_Sql, '@ColList@', @_ColList)
        SET        @_Sql = REPLACE(@_Sql, '@Cdcfntable@', @_Cdcfntable)
        SET        @_Sql = REPLACE(@_Sql, '@Column_name@', @_Columnname)
        SET        @_Sql = REPLACE(@_Sql, '@Tablename@', @_Tablename)
        SET        @_Sql = REPLACE(@_Sql, '@Starttime@', @_Starttime)
        SET        @_Sql = REPLACE(@_Sql, '@Endtime@', @_Endtime)
       


        IF @DML_Operation_Type='INSERT'
                BEGIN
                        SET @_Sql=@_Sql+' and  __$operation=2'
                END
        ELSE IF @DML_Operation_Type='DELETE'
                BEGIN
                        SET @_Sql=@_Sql+' and  __$operation =1'
                END
        ELSE IF @DML_Operation_Type='UPDATE'
                BEGIN
                        SET @_Sql=@_Sql+' and  __$operation in(4)'
                END

        ELSE IF @DML_Operation_Type IN ('DELETE,INSERT', 'INSERT,DELETE')
                BEGIN
                        SET @_Sql=@_Sql+' and  __$operation in (1,2)'
                END
        ELSE IF @DML_Operation_Type IN ('UPDATE,INSERT', 'INSERT,UPDATE')
                BEGIN
                        SET @_Sql=@_Sql+' and  __$operation in(2,4)'
                END
        ELSE IF @DML_Operation_Type IN ('UPDATE,DELETE' , 'DELETE,UPDATE')
                BEGIN
                        SET @_Sql=@_Sql+' and  __$operation in(1,4)'
                END
--PRINT @DML_Operation_Type

        PRINT @_Sql
        exec (@_Sql)

GO

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/16754036/viewspace-710968/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2009-07-06

  • 博文量
    116
  • 访问量
    313580