sqlserver 误删数据恢复

----创建存储过程

CREATE PROCEDURE Recover_Deleted_Data_Proc

    @Database_Name NVARCHAR(MAX) ,

    @SchemaName_n_TableName NVARCHAR(MAX) ,

    @Date_From DATETIME = '1900/01/01' ,

    @Date_To DATETIME = '9999/12/31'

AS

    DECLARE @RowLogContents VARBINARY(8000)

    DECLARE @TransactionID NVARCHAR(MAX)

    DECLARE @AllocUnitID BIGINT

    DECLARE @AllocUnitName NVARCHAR(MAX)

    DECLARE @SQL NVARCHAR(MAX)

    DECLARE @Compatibility_Level INT

 

 

    SELECT  @Compatibility_Level = dtb.compatibility_level

    FROM    master.sys.databases AS dtb

    WHERE   dtb.name = @Database_Name

 

    IF ISNULL(@Compatibility_Level, 0) <= 80

        BEGIN

            RAISERROR('The compatibility level should be equal to or greater SQL SERVER 2005 (90)',16,1)

            RETURN

        END

 

    IF ( SELECT COUNT(*)

         FROM   INFORMATION_SCHEMA.TABLES

         WHERE  [TABLE_SCHEMA] + '.' + [TABLE_NAME] = @SchemaName_n_TableName

       ) = 0

        BEGIN

            RAISERROR('Could not found the table in the defined database',16,1)

            RETURN

        END

 

    DECLARE @bitTable TABLE

        (

          [ID] INT ,

          [Bitvalue] INT

        )

--Create table to set the bit position of one byte.

 

    INSERT  INTO @bitTable

            SELECT  0 ,

                    2

            UNION ALL

            SELECT  1 ,

                    2

            UNION ALL

            SELECT  2 ,

                    4

            UNION ALL

            SELECT  3 ,

                    8

            UNION ALL

            SELECT  4 ,

                    16

            UNION ALL

            SELECT  5 ,

                    32

            UNION ALL

            SELECT  6 ,

                    64

            UNION ALL

            SELECT  7 ,

                    128

 

--Create table to collect the row data.

    DECLARE @DeletedRecords TABLE

        (

          [Row ID] INT IDENTITY(1, 1) ,

          [RowLogContents] VARBINARY(8000) ,

          [AllocUnitID] BIGINT ,

          [Transaction ID] NVARCHAR(MAX) ,

          [FixedLengthData] SMALLINT ,

          [TotalNoOfCols] SMALLINT ,

          [NullBitMapLength] SMALLINT ,

          [NullBytes] VARBINARY(8000) ,

          [TotalNoofVarCols] SMALLINT ,

          [ColumnOffsetArray] VARBINARY(8000) ,

          [VarColumnStart] SMALLINT ,

          [Slot ID] INT ,

          [NullBitMap] VARCHAR(MAX)

        )

--Create a common table expression to get all the row data plus how many bytes we have for each row.

;

    WITH    RowData

              AS ( SELECT   [RowLog Contents 0] AS [RowLogContents] ,

                            [AllocUnitID] AS [AllocUnitID] ,

                            [Transaction ID] AS [Transaction ID]  

 

--[Fixed Length Data] = Substring (RowLog content 0, Status Bit A+ Status Bit B + 1,2 bytes)

                            ,

                            CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) AS [FixedLengthData]  --@FixedLengthData

 

-- [TotalnoOfCols] =  Substring (RowLog content 0, [Fixed Length Data] + 1,2 bytes)

                            ,

                            CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 1,

                                                              2)))) AS [TotalNoOfCols]

 

--[NullBitMapLength]=ceiling([Total No of Columns] /8.0)

                            ,

                            CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 1,

                                                              2)))) / 8.0)) AS [NullBitMapLength] 

 

--[Null Bytes] = Substring (RowLog content 0, Status Bit A+ Status Bit B + [Fixed Length Data] +1, [NullBitMapLength] )

                            ,

                            SUBSTRING([RowLog Contents 0],

                                      CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 3,

                                      CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 1,

                                                              2)))) / 8.0))) AS [NullBytes]

 

--[TotalNoofVarCols] = Substring (RowLog content 0, Status Bit A+ Status Bit B + [Fixed Length Data] +1, [Null Bitmap length] + 2 )

                            ,

                            ( CASE WHEN SUBSTRING([RowLog Contents 0], 1, 1) IN (

                                        0x10, 0x30, 0x70 )

                                   THEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 3

                                                              + CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 1,

                                                              2)))) / 8.0)), 2))))

                                   ELSE NULL

                              END ) AS [TotalNoofVarCols] 

 

--[ColumnOffsetArray]= Substring (RowLog content 0, Status Bit A+ Status Bit B + [Fixed Length Data] +1, [Null Bitmap length] + 2 , [TotalNoofVarCols]*2 )

                            ,

                            ( CASE WHEN SUBSTRING([RowLog Contents 0], 1, 1) IN (

                                        0x10, 0x30, 0x70 )

                                   THEN SUBSTRING([RowLog Contents 0],

                                                  CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 3

                                                  + CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 1,

                                                              2)))) / 8.0))

                                                  + 2,

                                                  ( CASE WHEN SUBSTRING([RowLog Contents 0],

                                                              1, 1) IN ( 0x10,

                                                              0x30, 0x70 )

                                                         THEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 3

                                                              + CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 1,

                                                              2)))) / 8.0)), 2))))

                                                         ELSE NULL

                                                    END ) * 2)

                                   ELSE NULL

                              END ) AS [ColumnOffsetArray] 

 

--  Variable column Start = Status Bit A+ Status Bit B + [Fixed Length Data] + [Null Bitmap length] + 2+([TotalNoofVarCols]*2)

                            ,

                            CASE WHEN SUBSTRING([RowLog Contents 0], 1, 1) IN (

                                      0x10, 0x30, 0x70 )

                                 THEN ( CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 4

                                        + CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 1,

                                                              2)))) / 8.0))

                                        + ( ( CASE WHEN SUBSTRING([RowLog Contents 0],

                                                              1, 1) IN ( 0x10,

                                                              0x30, 0x70 )

                                                   THEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 3

                                                              + CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              2 + 1, 2)))) + 1,

                                                              2)))) / 8.0)), 2))))

                                                   ELSE NULL

                                              END ) * 2 ) )

                                 ELSE NULL

                            END AS [VarColumnStart] ,

                            [Slot ID]

                   FROM     sys.fn_dblog(NULL, NULL)

                   WHERE    AllocUnitId IN (

                            SELECT  [Allocation_unit_id]

                            FROM    sys.allocation_units allocunits

                                    INNER JOIN sys.partitions partitions ON ( allocunits.type IN (

                                                              1, 3 )

                                                              AND partitions.hobt_id = allocunits.container_id

                                                              )

                                                              OR ( allocunits.type = 2

                                                              AND partitions.partition_id = allocunits.container_id

                                                              )

                            WHERE   object_id = OBJECT_ID(''

                                                          + @SchemaName_n_TableName

                                                          + '') )

                            AND Context IN ( 'LCX_MARK_AS_GHOST', 'LCX_HEAP' )

                            AND Operation IN ( 'LOP_DELETE_ROWS' )

                            AND SUBSTRING([RowLog Contents 0], 1, 1) IN ( 0x10,

                                                              0x30, 0x70 )

 

/*Use this subquery to filter the date*/

                            AND [TRANSACTION ID] IN (

                            SELECT DISTINCT

                                    [TRANSACTION ID]

                            FROM    sys.fn_dblog(NULL, NULL)

                            WHERE   Context IN ( 'LCX_NULL' )

                                    AND Operation IN ( 'LOP_BEGIN_XACT' )

                                    AND [Transaction Name] IN ( 'DELETE',

                                                              'user_transaction' )

                                    AND CONVERT(NVARCHAR(11), [Begin Time]) BETWEEN @Date_From

                                                              AND

                                                              @Date_To )

                 ),

 

--Use this technique to repeate the row till the no of bytes of the row.

            N1 ( n )

              AS ( SELECT   1

                   UNION ALL

                   SELECT   1

                 ),

            N2 ( n )

              AS ( SELECT   1

                   FROM     N1 AS X ,

                            N1 AS Y

                 ),

            N3 ( n )

              AS ( SELECT   1

                   FROM     N2 AS X ,

                            N2 AS Y

                 ),

            N4 ( n )

              AS ( SELECT   ROW_NUMBER() OVER ( ORDER BY X.n )

                   FROM     N3 AS X ,

                            N3 AS Y

                 )

        INSERT  INTO @DeletedRecords

                SELECT  RowLogContents ,

                        [AllocUnitID] ,

                        [Transaction ID] ,

                        [FixedLengthData] ,

                        [TotalNoOfCols] ,

                        [NullBitMapLength] ,

                        [NullBytes] ,

                        [TotalNoofVarCols] ,

                        [ColumnOffsetArray] ,

                        [VarColumnStart] ,

                        [Slot ID]

         ---Get the Null value against each column (1 means null zero means not null)

                        ,

                        [NullBitMap] = ( REPLACE(STUFF(( SELECT

                                                              ','

                                                              + ( CASE

                                                              WHEN [ID] = 0

                                                              THEN CONVERT(NVARCHAR(1), ( SUBSTRING(NullBytes,

                                                              n, 1) % 2 ))

                                                              ELSE CONVERT(NVARCHAR(1), ( ( SUBSTRING(NullBytes,

                                                              n, 1)

                                                              / [Bitvalue] )

                                                              % 2 ))

                                                              END ) --as [nullBitMap]

                                                         FROM N4 AS Nums

                                                              JOIN RowData AS C ON n <= NullBitMapLength

                                                              CROSS JOIN @bitTable

                                                         WHERE

                                                              C.[RowLogContents] = D.[RowLogContents]

                                                         ORDER BY [RowLogContents] ,

                                                              n ASC

                                                       FOR

                                                         XML PATH('')

                                                       ), 1, 1, ''), ',', '') )

                FROM    RowData D

 

    IF ( SELECT COUNT(*)

         FROM   @DeletedRecords

       ) = 0

        BEGIN

            RAISERROR('There is no data in the log as per the search criteria',16,1)

            RETURN

        END

 

    DECLARE @ColumnNameAndData TABLE

        (

          [Row ID] INT ,

          [Rowlogcontents] VARBINARY(MAX) ,

          [NAME] SYSNAME ,

          [nullbit] SMALLINT ,

          [leaf_offset] SMALLINT ,

          [length] SMALLINT ,

          [system_type_id] TINYINT ,

          [bitpos] TINYINT ,

          [xprec] TINYINT ,

          [xscale] TINYINT ,

          [is_null] INT ,

          [Column value Size] INT ,

          [Column Length] INT ,

          [hex_Value] VARBINARY(MAX) ,

          [Slot ID] INT ,

          [Update] INT

        )

 

--Create common table expression and join it with the rowdata table

-- to get each column details

/*This part is for variable data columns*/

--@RowLogContents, 

--(col.columnOffValue - col.columnLength) + 1,

--col.columnLength

--)

    INSERT  INTO @ColumnNameAndData

            SELECT  [Row ID] ,

                    Rowlogcontents ,

                    NAME ,

                    cols.leaf_null_bit AS nullbit ,

                    leaf_offset ,

                    ISNULL(syscolumns.length, cols.max_length) AS [length] ,

                    cols.system_type_id ,

                    cols.leaf_bit_position AS bitpos ,

                    ISNULL(syscolumns.xprec, cols.precision) AS xprec ,

                    ISNULL(syscolumns.xscale, cols.scale) AS xscale ,

                    SUBSTRING([nullBitMap], cols.leaf_null_bit, 1) AS is_null ,

                    ( CASE WHEN leaf_offset < 1

                                AND SUBSTRING([nullBitMap], cols.leaf_null_bit,

                                              1) = 0

                           THEN ( CASE WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) > 30000

                                       THEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2))))

                                            - POWER(2, 15)

                                       ELSE CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2))))

                                  END )

                      END ) AS [Column value Size] ,

                    ( CASE WHEN leaf_offset < 1

                                AND SUBSTRING([nullBitMap], cols.leaf_null_bit,

                                              1) = 0

                           THEN ( CASE WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) > 30000

                                            AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                       [varColumnStart]) < 30000

                                       THEN ( CASE WHEN [System_type_id] IN (

                                                        35, 34, 99 ) THEN 16

                                                   ELSE 24

                                              END )

                                       WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) > 30000

                                            AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                       [varColumnStart]) > 30000

                                       THEN ( CASE WHEN [System_type_id] IN (

                                                        35, 34, 99 ) THEN 16

                                                   ELSE 24

                                              END ) --24 

                                       WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) < 30000

                                            AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                       [varColumnStart]) < 30000

                                       THEN ( CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2))))

                                              - ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                       [varColumnStart]) )

                                       WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) < 30000

                                            AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                       [varColumnStart]) > 30000

                                       THEN POWER(2, 15)

                                            + CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2))))

                                            - ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                     [varColumnStart])

                                  END )

                      END ) AS [Column Length] ,

                    ( CASE WHEN SUBSTRING([nullBitMap], cols.leaf_null_bit, 1) = 1

                           THEN NULL

                           ELSE SUBSTRING(Rowlogcontents,

                                          ( ( CASE WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) > 30000

                                                   THEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2))))

                                                        - POWER(2, 15)

                                                   ELSE CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2))))

                                              END )

                                            - ( CASE WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) > 30000

                                                          AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                              [varColumnStart]) < 30000

                                                     THEN ( CASE

                                                              WHEN [System_type_id] IN (

                                                              35, 34, 99 )

                                                              THEN 16

                                                              ELSE 24

                                                            END ) --24 

                                                     WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) > 30000

                                                          AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                              [varColumnStart]) > 30000

                                                     THEN ( CASE

                                                              WHEN [System_type_id] IN (

                                                              35, 34, 99 )

                                                              THEN 16

                                                              ELSE 24

                                                            END ) --24 

                                                     WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) < 30000

                                                          AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                              [varColumnStart]) < 30000

                                                     THEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2))))

                                                          - ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                              [varColumnStart])

                                                     WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) < 30000

                                                          AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                              [varColumnStart]) > 30000

                                                     THEN POWER(2, 15)

                                                          + CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2))))

                                                          - ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                              [varColumnStart])

                                                END ) ) + 1,

                                          ( CASE WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) > 30000

                                                      AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                              [varColumnStart]) < 30000

                                                 THEN ( CASE WHEN [System_type_id] IN (

                                                              35, 34, 99 )

                                                             THEN 16

                                                             ELSE 24

                                                        END ) --24 

                                                 WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) > 30000

                                                      AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                              [varColumnStart]) > 30000

                                                 THEN ( CASE WHEN [System_type_id] IN (

                                                              35, 34, 99 )

                                                             THEN 16

                                                             ELSE 24

                                                        END ) --24 

                                                 WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) < 30000

                                                      AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                              [varColumnStart]) < 30000

                                                 THEN ABS(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2))))

                                                          - ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                              [varColumnStart]))

                                                 WHEN CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2)))) < 30000

                                                      AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                              [varColumnStart]) > 30000

                                                 THEN POWER(2, 15)

                                                      + CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * leaf_offset

                                                              * -1 ) - 1, 2))))

                                                      - ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray],

                                                              ( 2

                                                              * ( ( leaf_offset

                                                              * -1 ) - 1 ) )

                                                              - 1, 2)))), 0),

                                                              [varColumnStart])

                                            END ))

                      END ) AS hex_Value ,

                    [Slot ID] ,

                    0

            FROM    @DeletedRecords A

                    INNER JOIN sys.allocation_units allocunits ON A.[AllocUnitId] = allocunits.[Allocation_Unit_Id]

                    INNER JOIN sys.partitions partitions ON ( allocunits.type IN (

                                                              1, 3 )

                                                              AND partitions.hobt_id = allocunits.container_id

                                                            )

                                                            OR ( allocunits.type = 2

                                                              AND partitions.partition_id = allocunits.container_id

                                                              )

                    INNER JOIN sys.system_internals_partition_columns cols ON cols.partition_id = partitions.partition_id

                    LEFT OUTER JOIN syscolumns ON syscolumns.id = partitions.object_id

                                                  AND syscolumns.colid = cols.partition_column_id

            WHERE   leaf_offset < 0

            UNION

/*This part is for fixed data columns*/

            SELECT  [Row ID] ,

                    Rowlogcontents ,

                    NAME ,

                    cols.leaf_null_bit AS nullbit ,

                    leaf_offset ,

                    ISNULL(syscolumns.length, cols.max_length) AS [length] ,

                    cols.system_type_id ,

                    cols.leaf_bit_position AS bitpos ,

                    ISNULL(syscolumns.xprec, cols.precision) AS xprec ,

                    ISNULL(syscolumns.xscale, cols.scale) AS xscale ,

                    SUBSTRING([nullBitMap], cols.leaf_null_bit, 1) AS is_null ,

                    ( SELECT TOP 1

                                ISNULL(SUM(CASE WHEN C.leaf_offset > 1

                                                THEN max_length

                                                ELSE 0

                                           END), 0)

                      FROM      sys.system_internals_partition_columns C

                      WHERE     cols.partition_id = C.partition_id

                                AND C.leaf_null_bit < cols.leaf_null_bit

                    ) + 5 AS [Column value Size] ,

                    syscolumns.length AS [Column Length] ,

                    CASE WHEN SUBSTRING([nullBitMap], cols.leaf_null_bit, 1) = 1

                         THEN NULL

                         ELSE SUBSTRING(Rowlogcontents,

                                        ( SELECT TOP 1

                                                    ISNULL(SUM(CASE

                                                              WHEN C.leaf_offset > 1

                                                              AND C.leaf_bit_position = 0

                                                              THEN max_length

                                                              ELSE 0

                                                              END), 0)

                                          FROM      sys.system_internals_partition_columns C

                                          WHERE     cols.partition_id = C.partition_id

                                                    AND C.leaf_null_bit < cols.leaf_null_bit

                                        ) + 5, syscolumns.length)

                    END AS hex_Value ,

                    [Slot ID] ,

                    0

            FROM    @DeletedRecords A

                    INNER JOIN sys.allocation_units allocunits ON A.[AllocUnitId] = allocunits.[Allocation_Unit_Id]

                    INNER JOIN sys.partitions partitions ON ( allocunits.type IN (

                                                              1, 3 )

                                                              AND partitions.hobt_id = allocunits.container_id

                                                            )

                                                            OR ( allocunits.type = 2

                                                              AND partitions.partition_id = allocunits.container_id

                                                              )

                    INNER JOIN sys.system_internals_partition_columns cols ON cols.partition_id = partitions.partition_id

                    LEFT OUTER JOIN syscolumns ON syscolumns.id = partitions.object_id

                                                  AND syscolumns.colid = cols.partition_column_id

            WHERE   leaf_offset > 0

            ORDER BY nullbit

 

    DECLARE @BitColumnByte AS INT

    SELECT  @BitColumnByte = CONVERT(INT, CEILING(COUNT(*) / 8.0))

    FROM    @ColumnNameAndData

    WHERE   [System_Type_id] = 104;

    WITH    N1 ( n )

              AS ( SELECT   1

                   UNION ALL

                   SELECT   1

                 ),

            N2 ( n )

              AS ( SELECT   1

                   FROM     N1 AS X ,

                            N1 AS Y

                 ),

            N3 ( n )

              AS ( SELECT   1

                   FROM     N2 AS X ,

                            N2 AS Y

                 ),

            N4 ( n )

              AS ( SELECT   ROW_NUMBER() OVER ( ORDER BY X.n )

                   FROM     N3 AS X ,

                            N3 AS Y

                 ),

            CTE

              AS ( SELECT   RowLogContents ,

                            [nullbit] ,

                            [BitMap] = CONVERT(VARBINARY(1), CONVERT(INT, SUBSTRING(( REPLACE(STUFF(( SELECT

                                                              ','

                                                              + ( CASE

                                                              WHEN [ID] = 0

                                                              THEN CONVERT(NVARCHAR(1), ( SUBSTRING(hex_Value,

                                                              n, 1) % 2 ))

                                                              ELSE CONVERT(NVARCHAR(1), ( ( SUBSTRING(hex_Value,

                                                              n, 1)

                                                              / [Bitvalue] )

                                                              % 2 ))

                                                              END ) --as [nullBitMap]

                                                              FROM

                                                              N4 AS Nums

                                                              JOIN @ColumnNameAndData

                                                              AS C ON n <= @BitColumnByte

                                                              AND [System_Type_id] = 104

                                                              AND bitpos = 0

                                                              CROSS JOIN @bitTable

                                                              WHERE

                                                              C.[RowLogContents] = D.[RowLogContents]

                                                              ORDER BY [RowLogContents] ,

                                                              n ASC

                                                              FOR

                                                              XML

                                                              PATH('')

                                                              ), 1, 1, ''),

                                                              ',', '') ),

                                                              bitpos + 1, 1)))

                   FROM     @ColumnNameAndData D

                   WHERE    [System_Type_id] = 104

                 )

        UPDATE  A

        SET     [hex_Value] = [BitMap]

        FROM    @ColumnNameAndData A

                INNER JOIN CTE B ON A.[RowLogContents] = B.[RowLogContents]

                                    AND A.[nullbit] = B.[nullbit]

 

 

/**************Check for BLOB DATA TYPES******************************/

    DECLARE @Fileid INT

    DECLARE @Pageid INT

    DECLARE @Slotid INT

    DECLARE @CurrentLSN INT

    DECLARE @LinkID INT

    DECLARE @Context VARCHAR(50)

    DECLARE @ConsolidatedPageID VARCHAR(MAX)

    DECLARE @LCX_TEXT_MIX VARBINARY(MAX)

 

    DECLARE @temppagedata TABLE

        (

          [ParentObject] SYSNAME ,

          [Object] SYSNAME ,

          [Field] SYSNAME ,

          [Value] SYSNAME

        )

 

    DECLARE @pagedata TABLE

        (

          [Page ID] SYSNAME ,

          [File IDS] INT ,

          [Page IDS] INT ,

          [AllocUnitId] BIGINT ,

          [ParentObject] SYSNAME ,

          [Object] SYSNAME ,

          [Field] SYSNAME ,

          [Value] SYSNAME

        )

 

    DECLARE @ModifiedRawData TABLE

        (

          [ID] INT IDENTITY(1, 1) ,

          [PAGE ID] VARCHAR(MAX) ,

          [FILE IDS] INT ,

          [PAGE IDS] INT ,

          [Slot ID] INT ,

          [AllocUnitId] BIGINT ,

          [RowLog Contents 0_var] VARCHAR(MAX) ,

          [RowLog Length] VARCHAR(50) ,

          [RowLog Len] INT ,

          [RowLog Contents 0] VARBINARY(MAX) ,

          [Link ID] INT DEFAULT ( 0 ) ,

          [Update] INT

        )

 

    DECLARE Page_Data_Cursor CURSOR

    FOR

        /*We need to filter LOP_MODIFY_ROW,LOP_MODIFY_COLUMNS from log for deleted records of BLOB data type& Get its Slot No, Page ID & AllocUnit ID*/

            SELECT  LTRIM(RTRIM(REPLACE([Description], 'Deallocated', ''))) AS [PAGE ID] ,

                    [Slot ID] ,

                    [AllocUnitId] ,

                    NULL AS [RowLog Contents 0] ,

                    NULL AS [RowLog Contents 0] ,

                    Context

            FROM    sys.fn_dblog(NULL, NULL)

            WHERE   AllocUnitId IN (

                    SELECT  [Allocation_unit_id]

                    FROM    sys.allocation_units allocunits

                            INNER JOIN sys.partitions partitions ON ( allocunits.type IN (

                                                              1, 3 )

                                                              AND partitions.hobt_id = allocunits.container_id

                                                              )

                                                              OR ( allocunits.type = 2

                                                              AND partitions.partition_id = allocunits.container_id

                                                              )

                    WHERE   object_id = OBJECT_ID('' + @SchemaName_n_TableName

                                                  + '') )

                    AND Operation IN ( 'LOP_MODIFY_ROW' )

                    AND [Context] IN ( 'LCX_PFS' )

                    AND Description LIKE '%Deallocated%'

            /*Use this subquery to filter the date*/

                    AND [TRANSACTION ID] IN (

                    SELECT DISTINCT

                            [TRANSACTION ID]

                    FROM    sys.fn_dblog(NULL, NULL)

                    WHERE   Context IN ( 'LCX_NULL' )

                            AND Operation IN ( 'LOP_BEGIN_XACT' )

                            AND [Transaction Name] = 'DELETE'

                            AND CONVERT(NVARCHAR(11), [Begin Time]) BETWEEN @Date_From

                                                              AND

                                                              @Date_To )

            GROUP BY [Description] ,

                    [Slot ID] ,

                    [AllocUnitId] ,

                    Context

            UNION

            SELECT  [PAGE ID] ,

                    [Slot ID] ,

                    [AllocUnitId] ,

                    SUBSTRING([RowLog Contents 0], 15,

                              LEN([RowLog Contents 0])) AS [RowLog Contents 0] ,

                    CONVERT(INT, SUBSTRING([RowLog Contents 0], 7, 2)) ,

                    Context --,CAST(RIGHT([Current LSN],4) AS INT) AS [Current LSN]

            FROM    sys.fn_dblog(NULL, NULL)

            WHERE   AllocUnitId IN (

                    SELECT  [Allocation_unit_id]

                    FROM    sys.allocation_units allocunits

                            INNER JOIN sys.partitions partitions ON ( allocunits.type IN (

                                                              1, 3 )

                                                              AND partitions.hobt_id = allocunits.container_id

                                                              )

                                                              OR ( allocunits.type = 2

                                                              AND partitions.partition_id = allocunits.container_id

                                                              )

                    WHERE   object_id = OBJECT_ID('' + @SchemaName_n_TableName

                                                  + '') )

                    AND Context IN ( 'LCX_TEXT_MIX' )

                    AND Operation IN ( 'LOP_DELETE_ROWS' ) 

            /*Use this subquery to filter the date*/

                    AND [TRANSACTION ID] IN (

                    SELECT DISTINCT

                            [TRANSACTION ID]

                    FROM    sys.fn_dblog(NULL, NULL)

                    WHERE   Context IN ( 'LCX_NULL' )

                            AND Operation IN ( 'LOP_BEGIN_XACT' )

                            AND [Transaction Name] = 'DELETE'

                            AND CONVERT(NVARCHAR(11), [Begin Time]) BETWEEN @Date_From

                                                              AND

                                                              @Date_To )

                         

            /****************************************/

 

    OPEN Page_Data_Cursor

 

    FETCH NEXT FROM Page_Data_Cursor INTO @ConsolidatedPageID, @Slotid,

        @AllocUnitID, @LCX_TEXT_MIX, @LinkID, @Context

 

    WHILE @@FETCH_STATUS = 0

        BEGIN

            DECLARE @hex_pageid AS VARCHAR(MAX)

            /*Page ID contains File Number and page number It looks like 0001:00000130.

              In this example 0001 is file Number &  00000130 is Page Number & These numbers are in Hex format*/

            SET @Fileid = SUBSTRING(@ConsolidatedPageID, 0,

                                    CHARINDEX(':', @ConsolidatedPageID)) -- Seperate File ID from Page ID

         

            SET @hex_pageid = '0x' + SUBSTRING(@ConsolidatedPageID,

                                               CHARINDEX(':',

                                                         @ConsolidatedPageID)

                                               + 1, LEN(@ConsolidatedPageID))  ---Seperate the page ID

            SELECT  @Pageid = CONVERT(INT, CAST('' AS XML).value('xs:hexBinary(substring(sql:variable("@hex_pageid"),sql:column("t.pos")) )',

                                                              'varbinary(max)')) -- Convert Page ID from hex to integer

            FROM    ( SELECT    CASE SUBSTRING(@hex_pageid, 1, 2)

                                  WHEN '0x' THEN 3

                                  ELSE 0

                                END

                    ) AS t ( pos ) 

             

            IF @Context = 'LCX_PFS'

                BEGIN

                    DELETE  @temppagedata

                    INSERT  INTO @temppagedata

                            EXEC

                                ( 'DBCC PAGE(' + @DataBase_Name + ', '

                                  + @fileid + ', ' + @pageid

                                  + ', 1) with tableresults,no_infomsgs;'

                                ); 

                    INSERT  INTO @pagedata

                            SELECT  @ConsolidatedPageID ,

                                    @fileid ,

                                    @pageid ,

                                    @AllocUnitID ,

                                    [ParentObject] ,

                                    [Object] ,

                                    [Field] ,

                                    [Value]

                            FROM    @temppagedata

                END

            ELSE

                IF @Context = 'LCX_TEXT_MIX'

                    BEGIN

                        INSERT  INTO @ModifiedRawData

                                SELECT  @ConsolidatedPageID ,

                                        @fileid ,

                                        @pageid ,

                                        @Slotid ,

                                        @AllocUnitID ,

                                        NULL ,

                                        0 ,

                                        CONVERT(INT, CONVERT(VARBINARY, REVERSE(SUBSTRING(@LCX_TEXT_MIX,

                                                              11, 2)))) ,

                                        @LCX_TEXT_MIX ,

                                        @LinkID ,

                                        0

                    END    

            FETCH NEXT FROM Page_Data_Cursor INTO @ConsolidatedPageID, @Slotid,

                @AllocUnitID, @LCX_TEXT_MIX, @LinkID, @Context

        END

     

    CLOSE Page_Data_Cursor

    DEALLOCATE Page_Data_Cursor

 

    DECLARE @Newhexstring VARCHAR(MAX);

 

    --The data is in multiple rows in the page, so we need to convert it into one row as a single hex value.

    --This hex value is in string format

    INSERT  INTO @ModifiedRawData

            ( [PAGE ID] ,

              [FILE IDS] ,

              [PAGE IDS] ,

              [Slot ID] ,

              [AllocUnitId] ,

              [RowLog Contents 0_var] ,

              [RowLog Length]

            )

            SELECT  [Page ID] ,

                    [FILE IDS] ,

                    [PAGE IDS] ,

                    SUBSTRING([ParentObject],

                              CHARINDEX('Slot', [ParentObject]) + 4,

                              ( CHARINDEX('Offset', [ParentObject])

                                - ( CHARINDEX('Slot', [ParentObject]) + 4 ) )

                              - 2) AS [Slot ID] ,

                    [AllocUnitId] ,

                    SUBSTRING(( SELECT  REPLACE(STUFF(( SELECT

                                                              REPLACE(SUBSTRING([Value],

                                                              CHARINDEX(':',

                                                              [Value]) + 1,

                                                              CHARINDEX('',

                                                              [Value])

                                                              - CHARINDEX(':',

                                                              [Value])), '',

                                                              '')

                                                        FROM  @pagedata C

                                                        WHERE B.[Page ID] = C.[Page ID]

                                                              AND SUBSTRING(B.[ParentObject],

                                                              CHARINDEX('Slot',

                                                              B.[ParentObject])

                                                              + 4,

                                                              ( CHARINDEX('Offset',

                                                              B.[ParentObject])

                                                              - ( CHARINDEX('Slot',

                                                              B.[ParentObject])

                                                              + 4 ) )) = SUBSTRING(C.[ParentObject],

                                                              CHARINDEX('Slot',

                                                              C.[ParentObject])

                                                              + 4,

                                                              ( CHARINDEX('Offset',

                                                              C.[ParentObject])

                                                              - ( CHARINDEX('Slot',

                                                              C.[ParentObject])

                                                              + 4 ) ))

                                                              AND [Object] LIKE '%Memory Dump%'

                                                        ORDER BY '0x'

                                                              + LEFT([Value],

                                                              CHARINDEX(':',

                                                              [Value]) - 1)

                                                      FOR

                                                        XML PATH('')

                                                      ), 1, 1, ''), ' ', '')

                              ), 1, 20000) AS [Value] ,

                    SUBSTRING(( SELECT  '0x'

                                        + REPLACE(STUFF(( SELECT

                                                              REPLACE(SUBSTRING([Value],

                                                              CHARINDEX(':',

                                                              [Value]) + 1,

                                                              CHARINDEX('',

                                                              [Value])

                                                              - CHARINDEX(':',

                                                              [Value])), '',

                                                              '')

                                                          FROM

                                                              @pagedata C

                                                          WHERE

                                                              B.[Page ID] = C.[Page ID]

                                                              AND SUBSTRING(B.[ParentObject],

                                                              CHARINDEX('Slot',

                                                              B.[ParentObject])

                                                              + 4,

                                                              ( CHARINDEX('Offset',

                                                              B.[ParentObject])

                                                              - ( CHARINDEX('Slot',

                                                              B.[ParentObject])

                                                              + 4 ) )) = SUBSTRING(C.[ParentObject],

                                                              CHARINDEX('Slot',

                                                              C.[ParentObject])

                                                              + 4,

                                                              ( CHARINDEX('Offset',

                                                              C.[ParentObject])

                                                              - ( CHARINDEX('Slot',

                                                              C.[ParentObject])

                                                              + 4 ) ))

                                                              AND [Object] LIKE '%Memory Dump%'

                                                          ORDER BY '0x'

                                                              + LEFT([Value],

                                                              CHARINDEX(':',

                                                              [Value]) - 1)

                                                        FOR

                                                          XML PATH('')

                                                        ), 1, 1, ''), ' ', '')

                              ), 7, 4) AS [Length]

            FROM    @pagedata B

            WHERE   [Object] LIKE '%Memory Dump%'

            GROUP BY [Page ID] ,

                    [FILE IDS] ,

                    [PAGE IDS] ,

                    [ParentObject] ,

                    [AllocUnitId]--,[Current LSN]

            ORDER BY [Slot ID]

 

    UPDATE  @ModifiedRawData

    SET     [RowLog Len] = CONVERT(VARBINARY(8000), REVERSE(CAST('' AS XML).value('xs:hexBinary(substring(sql:column("[RowLog Length]"),0))',

                                                              'varbinary(Max)')))

    FROM    @ModifiedRawData

    WHERE   [LINK ID] = 0

 

    UPDATE  @ModifiedRawData

    SET     [RowLog Contents 0] = CAST('' AS XML).value('xs:hexBinary(substring(sql:column("[RowLog Contents 0_var]"),0))',

                                                        'varbinary(Max)')

    FROM    @ModifiedRawData

    WHERE   [LINK ID] = 0

 

    UPDATE  B

    SET     B.[RowLog Contents 0] = ( CASE WHEN A.[RowLog Contents 0] IS NOT NULL

                                                AND C.[RowLog Contents 0] IS NOT NULL

                                           THEN A.[RowLog Contents 0]

                                                + C.[RowLog Contents 0]

                                           WHEN A.[RowLog Contents 0] IS NULL

                                                AND C.[RowLog Contents 0] IS NOT NULL

                                           THEN C.[RowLog Contents 0]

                                           WHEN A.[RowLog Contents 0] IS NOT NULL

                                                AND C.[RowLog Contents 0] IS NULL

                                           THEN A.[RowLog Contents 0]

                                      END ) ,

            B.[Update] = ISNULL(B.[Update], 0) + 1

    FROM    @ModifiedRawData B

            LEFT JOIN @ModifiedRawData A ON A.[Page IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents 0],

                                                              15 + 14, 2))))

                                            AND A.[File IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents 0],

                                                              19 + 14, 2))))

                                            AND A.[Link ID] = B.[Link ID]

            LEFT JOIN @ModifiedRawData C ON C.[Page IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents 0],

                                                              27 + 14, 2))))

                                            AND C.[File IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents 0],

                                                              31 + 14, 2))))

                                            AND C.[Link ID] = B.[Link ID]

    WHERE   ( A.[RowLog Contents 0] IS NOT NULL

              OR C.[RowLog Contents 0] IS NOT NULL

            )

 

 

    UPDATE  B

    SET     B.[RowLog Contents 0] = ( CASE WHEN A.[RowLog Contents 0] IS NOT NULL

                                                AND C.[RowLog Contents 0] IS NOT NULL

                                           THEN A.[RowLog Contents 0]

                                                + C.[RowLog Contents 0]

                                           WHEN A.[RowLog Contents 0] IS NULL

                                                AND C.[RowLog Contents 0] IS NOT NULL

                                           THEN C.[RowLog Contents 0]

                                           WHEN A.[RowLog Contents 0] IS NOT NULL

                                                AND C.[RowLog Contents 0] IS NULL

                                           THEN A.[RowLog Contents 0]

                                      END )

    --,B.[Update]=ISNULL(B.[Update],0)+1

    FROM    @ModifiedRawData B

            LEFT JOIN @ModifiedRawData A ON A.[Page IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents 0],

                                                              15 + 14, 2))))

                                            AND A.[File IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents 0],

                                                              19 + 14, 2))))

                                            AND A.[Link ID] <> B.[Link ID]

                                            AND B.[Update] = 0

            LEFT JOIN @ModifiedRawData C ON C.[Page IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents 0],

                                                              27 + 14, 2))))

                                            AND C.[File IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents 0],

                                                              31 + 14, 2))))

                                            AND C.[Link ID] <> B.[Link ID]

                                            AND B.[Update] = 0

    WHERE   ( A.[RowLog Contents 0] IS NOT NULL

              OR C.[RowLog Contents 0] IS NOT NULL

            )

 

    UPDATE  @ModifiedRawData

    SET     [RowLog Contents 0] = ( CASE WHEN [RowLog Len] >= 8000

                                         THEN SUBSTRING([RowLog Contents 0],

                                                        15, [RowLog Len])

                                         WHEN [RowLog Len] < 8000

                                         THEN SUBSTRING([RowLog Contents 0],

                                                        15 + 6,

                                                        CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([RowLog Contents 0],

                                                              15, 6)))))

                                    END )

    FROM    @ModifiedRawData

    WHERE   [LINK ID] = 0

 

    UPDATE  @ColumnNameAndData

    SET     [hex_Value] = [RowLog Contents 0] 

    --,A.[Update]=A.[Update]+1

    FROM    @ColumnNameAndData A

            INNER JOIN @ModifiedRawData B ON CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value],

                                                              17, 4)))) = [PAGE IDS]

                                             AND CONVERT(INT, SUBSTRING([hex_value],

                                                              9, 2)) = B.[Link ID]

    WHERE   [System_Type_Id] IN ( 99, 167, 175, 231, 239, 241, 165, 98 )

            AND [Link ID] <> 0 

 

    UPDATE  @ColumnNameAndData

    SET     [hex_Value] = ( CASE WHEN B.[RowLog Contents 0] IS NOT NULL

                                      AND C.[RowLog Contents 0] IS NOT NULL

                                 THEN B.[RowLog Contents 0]

                                      + C.[RowLog Contents 0]

                                 WHEN B.[RowLog Contents 0] IS NULL

                                      AND C.[RowLog Contents 0] IS NOT NULL

                                 THEN C.[RowLog Contents 0]

                                 WHEN B.[RowLog Contents 0] IS NOT NULL

                                      AND C.[RowLog Contents 0] IS NULL

                                 THEN B.[RowLog Contents 0]

                            END )

    --,A.[Update]=A.[Update]+1

    FROM    @ColumnNameAndData A

            LEFT JOIN @ModifiedRawData B ON CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value],

                                                              5, 4)))) = B.[PAGE IDS]

                                            AND B.[Link ID] = 0

            LEFT JOIN @ModifiedRawData C ON CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value],

                                                              17, 4)))) = C.[PAGE IDS]

                                            AND C.[Link ID] = 0

    WHERE   [System_Type_Id] IN ( 99, 167, 175, 231, 239, 241, 165, 98 )

            AND ( B.[RowLog Contents 0] IS NOT NULL

                  OR C.[RowLog Contents 0] IS NOT NULL

                )

 

    UPDATE  @ColumnNameAndData

    SET     [hex_Value] = [RowLog Contents 0] 

    --,A.[Update]=A.[Update]+1

    FROM    @ColumnNameAndData A

            INNER JOIN @ModifiedRawData B ON CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value],

                                                              9, 4)))) = [PAGE IDS]

                                             AND CONVERT(INT, SUBSTRING([hex_value],

                                                              3, 2)) = [Link ID]

    WHERE   [System_Type_Id] IN ( 35, 34, 99 )

            AND [Link ID] <> 0 

     

    UPDATE  @ColumnNameAndData

    SET     [hex_Value] = [RowLog Contents 0]

    --,A.[Update]=A.[Update]+10

    FROM    @ColumnNameAndData A

            INNER JOIN @ModifiedRawData B ON CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value],

                                                              9, 4)))) = [PAGE IDS]

    WHERE   [System_Type_Id] IN ( 35, 34, 99 )

            AND [Link ID] = 0

 

    UPDATE  @ColumnNameAndData

    SET     [hex_Value] = [RowLog Contents 0] 

    --,A.[Update]=A.[Update]+1

    FROM    @ColumnNameAndData A

            INNER JOIN @ModifiedRawData B ON CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value],

                                                              15, 4)))) = [PAGE IDS]

    WHERE   [System_Type_Id] IN ( 35, 34, 99 )

            AND [Link ID] = 0

 

    UPDATE  @ColumnNameAndData

    SET     [hex_value] = 0xFFFE + SUBSTRING([hex_value], 9, LEN([hex_value]))

    --,[Update]=[Update]+1

    WHERE   [system_type_id] = 241

 

    CREATE TABLE [#temp_Data]

        (

          [FieldName] VARCHAR(MAX) ,

          [FieldValue] NVARCHAR(MAX) ,

          [Rowlogcontents] VARBINARY(8000) ,

          [Row ID] INT

        )

 

    INSERT  INTO #temp_Data

            SELECT  NAME ,

                    CASE WHEN system_type_id IN ( 231, 239 )

                         THEN LTRIM(RTRIM(CONVERT(NVARCHAR(MAX), hex_Value)))  --NVARCHAR ,NCHAR

                         WHEN system_type_id IN ( 167, 175 )

                         THEN LTRIM(RTRIM(CONVERT(VARCHAR(MAX), hex_Value)))  --VARCHAR,CHAR

                         WHEN system_type_id IN ( 35 )

                         THEN LTRIM(RTRIM(CONVERT(VARCHAR(MAX), hex_Value))) --Text

                         WHEN system_type_id IN ( 99 )

                         THEN LTRIM(RTRIM(CONVERT(NVARCHAR(MAX), hex_Value))) --nText 

                         WHEN system_type_id = 48

                         THEN CONVERT(VARCHAR(MAX), CONVERT(TINYINT, CONVERT(BINARY(1), REVERSE(hex_Value)))) --TINY INTEGER

                         WHEN system_type_id = 52

                         THEN CONVERT(VARCHAR(MAX), CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(hex_Value)))) --SMALL INTEGER

                         WHEN system_type_id = 56

                         THEN CONVERT(VARCHAR(MAX), CONVERT(INT, CONVERT(BINARY(4), REVERSE(hex_Value)))) -- INTEGER

                         WHEN system_type_id = 127

                         THEN CONVERT(VARCHAR(MAX), CONVERT(BIGINT, CONVERT(BINARY(8), REVERSE(hex_Value))))-- BIG INTEGER

                         WHEN system_type_id = 61

                         THEN CONVERT(VARCHAR(MAX), CONVERT(DATETIME, CONVERT(VARBINARY(8000), REVERSE(hex_Value))), 100) --DATETIME

                         WHEN system_type_id = 58

                         THEN CONVERT(VARCHAR(MAX), CONVERT(SMALLDATETIME, CONVERT(VARBINARY(8000), REVERSE(hex_Value))), 100) --SMALL DATETIME

                         WHEN system_type_id = 108

                         THEN CONVERT(VARCHAR(MAX), CONVERT(NUMERIC(38, 20), CONVERT(VARBINARY, CONVERT(VARBINARY(1), xprec)

                              + CONVERT(VARBINARY(1), xscale))

                              + CONVERT(VARBINARY(1), 0) + hex_Value)) --- NUMERIC

                         WHEN system_type_id = 106

                         THEN CONVERT(VARCHAR(MAX), CONVERT(DECIMAL(38, 20), CONVERT(VARBINARY, CONVERT(VARBINARY(1), xprec)

                              + CONVERT(VARBINARY(1), xscale))

                              + CONVERT(VARBINARY(1), 0) + hex_Value)) --- DECIMAL

                         WHEN system_type_id IN ( 60, 122 )

                         THEN CONVERT(VARCHAR(MAX), CONVERT(MONEY, CONVERT(VARBINARY(8000), REVERSE(hex_Value))), 2) --MONEY,SMALLMONEY

                         WHEN system_type_id = 104

                         THEN CONVERT(VARCHAR(MAX), CONVERT (BIT, CONVERT(BINARY(1), hex_Value)

                              % 2))  -- BIT

                         WHEN system_type_id = 62

                         THEN RTRIM(LTRIM(STR(CONVERT(FLOAT, SIGN(CAST(CONVERT(VARBINARY(8000), REVERSE(hex_Value)) AS BIGINT))

                                              * ( 1.0

                                                  + ( CAST(CONVERT(VARBINARY(8000), REVERSE(hex_Value)) AS BIGINT)

                                                      & 0x000FFFFFFFFFFFFF )

                                                  * POWER(CAST(2 AS FLOAT),

                                                          -52) )

                                              * POWER(CAST(2 AS FLOAT),

                                                      ( ( CAST(CONVERT(VARBINARY(8000), REVERSE(hex_Value)) AS BIGINT)

                                                          & 0x7ff0000000000000 )

                                                        / EXP(52 * LOG(2))

                                                        - 1023 ))), 53,

                                              LEN(hex_Value)))) --- FLOAT

                         WHEN system_type_id = 59

                         THEN LEFT(LTRIM(STR(CAST(SIGN(CAST(CONVERT(VARBINARY(8000), REVERSE(hex_Value)) AS BIGINT))

                                             * ( 1.0

                                                 + ( CAST(CONVERT(VARBINARY(8000), REVERSE(hex_Value)) AS BIGINT)

                                                     & 0x007FFFFF )

                                                 * POWER(CAST(2 AS REAL), -23) )

                                             * POWER(CAST(2 AS REAL),

                                                     ( ( ( CAST(CONVERT(VARBINARY(8000), REVERSE(hex_Value)) AS INT) )

                                                         & 0x7f800000 )

                                                       / EXP(23 * LOG(2))

                                                       - 127 )) AS REAL), 23,

                                             23)), 8) --Real

                         WHEN system_type_id IN ( 165, 173 )

                         THEN ( CASE WHEN CHARINDEX(0x,

                                                    CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',

                                                              'VARBINARY(8000)')) = 0

                                     THEN '0x'

                                     ELSE ''

                                END ) + CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',

                                                              'varchar(max)') -- BINARY,VARBINARY

                         WHEN system_type_id = 34

                         THEN ( CASE WHEN CHARINDEX(0x,

                                                    CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',

                                                              'VARBINARY(8000)')) = 0

                                     THEN '0x'

                                     ELSE ''

                                END ) + CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',

                                                              'varchar(max)')  --IMAGE

                         WHEN system_type_id = 36

                         THEN CONVERT(VARCHAR(MAX), CONVERT(UNIQUEIDENTIFIER, hex_Value)) --UNIQUEIDENTIFIER

                         WHEN system_type_id = 231

                         THEN CONVERT(VARCHAR(MAX), CONVERT(SYSNAME, hex_Value)) --SYSNAME

                         WHEN system_type_id = 241

                         THEN CONVERT(VARCHAR(MAX), CONVERT(XML, hex_Value)) --XML

                         WHEN system_type_id = 189

                         THEN ( CASE WHEN CHARINDEX(0x,

                                                    CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',

                                                              'VARBINARY(8000)')) = 0

                                     THEN '0x'

                                     ELSE ''

                                END ) + CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',

                                                              'varchar(max)') --TIMESTAMP

                         WHEN system_type_id = 98

                         THEN ( CASE WHEN CONVERT(INT, SUBSTRING(hex_Value, 1,

                                                              1)) = 56

                                     THEN CONVERT(VARCHAR(MAX), CONVERT(INT, CONVERT(BINARY(4), REVERSE(SUBSTRING(hex_Value,

                                                              3,

                                                              LEN(hex_Value))))))  -- INTEGER

                                     WHEN CONVERT(INT, SUBSTRING(hex_Value, 1,

                                                              1)) = 108

                                     THEN CONVERT(VARCHAR(MAX), CONVERT(NUMERIC(38,

                                                              20), CONVERT(VARBINARY(1), SUBSTRING(hex_Value,

                                                              3, 1))

                                          + CONVERT(VARBINARY(1), SUBSTRING(hex_Value,

                                                              4, 1))

                                          + CONVERT(VARBINARY(1), 0)

                                          + SUBSTRING(hex_Value, 5,

                                                      LEN(hex_Value)))) --- NUMERIC

                                     WHEN CONVERT(INT, SUBSTRING(hex_Value, 1,

                                                              1)) = 167

                                     THEN LTRIM(RTRIM(CONVERT(VARCHAR(MAX), SUBSTRING(hex_Value,

                                                              9,

                                                              LEN(hex_Value))))) --VARCHAR,CHAR

                                     WHEN CONVERT(INT, SUBSTRING(hex_Value, 1,

                                                              1)) = 36

                                     THEN CONVERT(VARCHAR(MAX), CONVERT(UNIQUEIDENTIFIER, SUBSTRING(( hex_Value ),

                                                              3, 20))) --UNIQUEIDENTIFIER

                                     WHEN CONVERT(INT, SUBSTRING(hex_Value, 1,

                                                              1)) = 61

                                     THEN CONVERT(VARCHAR(MAX), CONVERT(DATETIME, CONVERT(VARBINARY(8000), REVERSE(SUBSTRING(hex_Value,

                                                              3,

                                                              LEN(hex_Value))))), 100) --DATETIME

                                     WHEN CONVERT(INT, SUBSTRING(hex_Value, 1,

                                                              1)) = 165

                                     THEN '0x'

                                          + SUBSTRING(( CASE WHEN CHARINDEX(0x,

                                                              CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',

                                                              'VARBINARY(8000)')) = 0

                                                             THEN '0x'

                                                             ELSE ''

                                                        END )

                                                      + CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',

                                                              'varchar(max)'),

                                                      11, LEN(hex_Value)) -- BINARY,VARBINARY

                                END )

                    END AS FieldValue ,

                    [Rowlogcontents] ,

                    [Row ID]

            FROM    @ColumnNameAndData

            ORDER BY nullbit

 

--Create the column name in the same order to do pivot table.

 

    DECLARE @FieldName VARCHAR(MAX)

    SET @FieldName = STUFF(( SELECT ','

                                    + CAST(QUOTENAME([Name]) AS VARCHAR(MAX))

                             FROM   syscolumns

                             WHERE  id = OBJECT_ID(''

                                                   + @SchemaName_n_TableName

                                                   + '')

                           FOR

                             XML PATH('')

                           ), 1, 1, '')

 

--Finally did pivot table and get the data back in the same format.

 

    SET @sql = 'SELECT ' + @FieldName

        + ' FROM #temp_Data PIVOT (Min([FieldValue]) FOR FieldName IN ('

        + @FieldName + ')) AS pvt'

    EXEC sp_executesql @sql

 

GO

---执行存储过程两个参数(数据库名,表名)

EXEC Recover_Deleted_Data_Proc '数据库名称','dbo.tableName'--表名前面要加dbo 不然会报错的。

--执行存储过程四个参数(数据库名称,表明,开始时间,结束时间【按照时间段来恢复】)

EXEC Recover_Deleted_Data_Proc '数据库名称','dbo.TableName','2014-04-23','2014-04-23'--表名要加dbo。

转自http://www.cnblogs.com/lyhabc/p/3683147.html#2924733.

你可能感兴趣的:(sqlserver)