转 --- 恢复误删数据
Posted 拂髯客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了转 --- 恢复误删数据相关的知识,希望对你有一定的参考价值。
曾经想实现Log Explorer for SQL Server的功能,利用ldf里面的日志来还原误删除的数据
这里有一篇文章做到了,不过似乎不是所有的数据类型都支持
以下为译文:http://raresql.com/2011/10/22/how-to-recover-deleted-data-from-sql-sever/
在我使用SQLSERVER的这些年里面,大部分人都会问我一个问题:“能不能恢复被删除的数据??”
现在,从SQLSERVER2005 或以上版本能很容易能够恢复被删除的数据
(注意:这个脚本能恢复下面的数据类型的数据 而且兼容CS 排序规则)
- image
- text
- uniqueidentifier
- tinyint
- smallint
- int
- smalldatetime
- real
- money
- datetime
- float
- sql_variant
- ntext
- bit
- decimal
- numeric
- smallmoney
- bigint
- varbinary
- varchar
- binary
- char
- timestamp
- nvarchar
- nchar
- xml
- sysname
让我来用demo来解释一下我是怎么做到的
USE master GO--创建数据库CREATEDATABASE test GOUSE[test]GO--创建表CREATETABLE[dbo].[aa]( [id][int]IDENTITY(1,1) NOTNULL, [NAME][nvarchar](200) NULL ) ON[PRIMARY]GO--插入测试数据INSERT[dbo].[aa] ( [NAME] ) SELECT\'你好\'GO--删除数据Deletefrom aa Go--验证数据是否已经删除Select*from aa Go
现在你需要创建一个存储过程来恢复你的数据
-- Script Name: Recover_Deleted_Data_Proc -- Script Type : Recovery Procedure -- Develop By: Muhammad Imran -- Date Created: 15 Oct 2011 -- Modify Date: 22 Aug 2012 -- Version : 3.1 -- Notes : Included BLOB data types for recovery.& Compatibile with Default , CS collation , Arabic_CI_AS.CREATEPROCEDURE Recover_Deleted_Data_Proc @Database_NameNVARCHAR(MAX) , @SchemaName_n_TableNameNVARCHAR(MAX) , @Date_FromDATETIME=\'1900/01/01\' , @Date_ToDATETIME=\'9999/12/31\'ASDECLARE@RowLogContentsVARBINARY(8000) DECLARE@TransactionIDNVARCHAR(MAX) DECLARE@AllocUnitIDBIGINTDECLARE@AllocUnitNameNVARCHAR(MAX) DECLARE@SQLNVARCHAR(MAX) DECLARE@Compatibility_LevelINTSELECT@Compatibility_Level= dtb.compatibility_level FROM master.sys.databases AS dtb WHERE dtb.name =@Database_NameIFISNULL(@Compatibility_Level, 0) <=80BEGINRAISERROR(\'The compatibility level should be equal to or greater SQL SERVER 2005 (90)\',16,1) RETURNENDIF ( SELECTCOUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE[TABLE_SCHEMA]+\'.\'+[TABLE_NAME]=@SchemaName_n_TableName ) =0BEGINRAISERROR(\'Could not found the table in the defined database\',16,1) RETURNENDDECLARE@bitTableTABLE ( [ID]INT , [Bitvalue]INT ) --Create table to set the bit position of one byte.INSERTINTO@bitTableSELECT0 , 2UNIONALLSELECT1 , 2UNIONALLSELECT2 , 4UNIONALLSELECT3 , 8UNIONALLSELECT4 , 16UNIONALLSELECT5 , 32UNIONALLSELECT6 , 64UNIONALLSELECT7 , 128--Create table to collect the row data.DECLARE@DeletedRecordsTABLE ( [Row ID]INTIDENTITY(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 ) , ( CASEWHENSUBSTRING([RowLog Contents 0], 1, 1) IN ( 0x10, 0x30, 0x70 ) THENCONVERT(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)))) ELSENULLEND ) AS[TotalNoofVarCols]--[ColumnOffsetArray]= Substring (RowLog content 0, Status Bit A+ Status Bit B + [Fixed Length Data] +1, [Null Bitmap length] + 2 , [TotalNoofVarCols]*2 ) , ( CASEWHENSUBSTRING([RowLog Contents 0], 1, 1) IN ( 0x10, 0x30, 0x70 ) THENSUBSTRING([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, ( CASEWHENSUBSTRING([RowLog Contents 0], 1, 1) IN ( 0x10, 0x30, 0x70 ) THENCONVERT(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)))) ELSENULLEND ) *2) ELSENULLEND ) AS[ColumnOffsetArray]-- Variable column Start = Status Bit A+ Status Bit B + [Fixed Length Data] + [Null Bitmap length] + 2+([TotalNoofVarCols]*2) , CASEWHENSUBSTRING([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)) + ( ( CASEWHENSUBSTRING([RowLog Contents 0], 1, 1) IN ( 0x10, 0x30, 0x70 ) THENCONVERT(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)))) ELSENULLEND ) *2 ) ) ELSENULLENDAS[VarColumnStart] , [Slot ID]FROM sys.fn_dblog(NULL, NULL) WHERE AllocUnitId IN ( SELECT[Allocation_unit_id]FROM sys.allocation_units allocunits INNERJOIN sys.partitions partitions ON ( allocunits.type IN ( 1, 3 ) AND partitions.hobt_id = allocunits.container_id ) OR ( allocunits.type =2AND partitions.partition_id = allocunits.container_id ) WHEREobject_id=OBJECT_ID(\'\'+@SchemaName_n_TableName+\'\') ) AND Context IN ( \'LCX_MARK_AS_GHOST\', \'LCX_HEAP\' ) AND Operation IN ( \'LOP_DELETE_ROWS\' ) ANDSUBSTRING([RowLog Contents 0], 1, 1) IN ( 0x10, 0x30, 0x70 ) /*Use this subquery to filter the date*/AND[TRANSACTION ID]IN ( SELECTDISTINCT[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\' ) ANDCONVERT(NVARCHAR(11), [Begin Time]) BETWEEN@Date_FromAND@Date_To ) ), --Use this technique to repeate the row till the no of bytes of the row. N1 ( n ) AS ( SELECT1UNIONALLSELECT1 ), N2 ( n ) AS ( SELECT1FROM N1 AS X , N1 AS Y ), N3 ( n ) AS ( SELECT1FROM N2 AS X , N2 AS Y ), N4 ( n ) AS ( SELECT ROW_NUMBER() OVER ( ORDERBY X.n ) FROM N3 AS X , N3 AS Y ) INSERTINTO@DeletedRecordsSELECT 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\',\'+ ( CASEWHEN[ID]=0THENCONVERT(NVARCHAR(1), ( SUBSTRING(NullBytes, n, 1) %2 )) ELSECONVERT(NVARCHAR(1), ( ( SUBSTRING(NullBytes, n, 1) /[Bitvalue] ) %2 )) END ) --as [nullBitMap]FROM N4 AS Nums JOIN RowData AS C ON n <= NullBitMapLength CROSSJOIN@bitTableWHERE C.[RowLogContents]= D.[RowLogContents]ORDERBY[RowLogContents] , n ASCFOR XML PATH(\'\') ), 1, 1, \'\'), \',\', \'\') ) FROM RowData D IF ( SELECTCOUNT(*) FROM@DeletedRecords ) =0BEGINRAISERROR(\'There is no data in the log as per the search criteria\',16,1) RETURNENDDECLARE@ColumnNameAndDataTABLE ( [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 --)INSERTINTO@ColumnNameAndDataSELECT[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 , ( CASEWHEN leaf_offset <1ANDSUBSTRING([nullBitMap], cols.leaf_null_bit, 1) =0THEN ( CASEWHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) >30000THENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) -POWER(2, 15) ELSECONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) END ) END ) AS[Column value Size] , ( CASEWHEN leaf_offset <1ANDSUBSTRING([nullBitMap], cols.leaf_null_bit, 1) =0THEN ( CASEWHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) >30000ANDISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* ( ( leaf_offset *-1 ) -1 ) ) -1, 2)))), 0), [varColumnStart]) <30000THEN ( CASEWHEN[System_type_id]IN ( 35, 34, 99 ) THEN16ELSE24END ) WHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) >30000ANDISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* ( ( leaf_offset *-1 ) -1 ) ) -1, 2)))), 0), [varColumnStart]) >30000THEN ( CASEWHEN[System_type_id]IN ( 35, 34, 99 ) THEN16ELSE24END ) --24 WHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) <30000ANDISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* ( ( leaf_offset *-1 ) -1 ) ) -1, 2)))), 0), [varColumnStart]) <30000THEN ( 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]) ) WHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) <30000ANDISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* ( ( leaf_offset *-1 ) -1 ) ) -1, 2)))), 0), [varColumnStart]) >30000THENPOWER(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] , ( CASEWHENSUBSTRING([nullBitMap], cols.leaf_null_bit, 1) =1THENNULLELSESUBSTRING(Rowlogcontents, ( ( CASEWHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) >30000THENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) -POWER(2, 15) ELSECONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) END ) - ( CASEWHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) >30000ANDISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* ( ( leaf_offset *-1 ) -1 ) ) -1, 2)))), 0), [varColumnStart]) <30000THEN ( CASEWHEN[System_type_id]IN ( 35, 34, 99 ) THEN16ELSE24END ) --24 WHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) >30000ANDISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* ( ( leaf_offset *-1 ) -1 ) ) -1, 2)))), 0), [varColumnStart]) >30000THEN ( CASEWHEN[System_type_id]IN ( 35, 34, 99 ) THEN16ELSE24END ) --24 WHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) <30000ANDISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* ( ( leaf_offset *-1 ) -1 ) ) -1, 2)))), 0), [varColumnStart]) <30000THENCONVERT(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]) WHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) <30000ANDISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* ( ( leaf_offset *-1 ) -1 ) ) -1, 2)))), 0), [varColumnStart]) >30000THENPOWER(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, ( CASEWHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) >30000ANDISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* ( ( leaf_offset *-1 ) -1 ) ) -1, 2)))), 0), [varColumnStart]) <30000THEN ( CASEWHEN[System_type_id]IN ( 35, 34, 99 ) THEN16ELSE24END ) --24 WHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) >30000ANDISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* ( ( leaf_offset *-1 ) -1 ) ) -1, 2)))), 0), [varColumnStart]) >30000THEN ( CASEWHEN[System_type_id]IN ( 35, 34, 99 ) THEN16ELSE24END ) --24 WHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) <30000ANDISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* ( ( leaf_offset *-1 ) -1 ) ) -1, 2)))), 0), [varColumnStart]) <30000THENABS(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])) WHENCONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* leaf_offset *-1 ) -1, 2)))) <30000ANDISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(2), REVERSE(SUBSTRING([ColumnOffsetArray], ( 2* ( ( leaf_offset *-1 ) -1 ) ) -1, 2)))), 0), [varColumnStart]) >30000THENPOWER(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] , 0FROM@DeletedRecords A INNERJOIN sys.allocation_units allocunits ON A.[AllocUnitId]= allocunits.[Allocation_Unit_Id]INNERJOIN sys.partitions partitions ON ( allocunits.type IN ( 1, 3 ) AND partitions.hobt_id = allocunits.container_id ) OR ( allocunits.type =2AND partitions.partition_id = allocunits.container_id ) INNERJOIN sys.system_internals_partition_columns cols ON cols.partition_id = partitions.partition_id LEFTOUTERJOIN syscolumns ON syscolumns.id = partitions.object_idAND syscolumns.colid = cols.partition_column_id WHERE leaf_offset <0UNION/*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 , ( SELECTTOP1ISNULL(SUM(CASEWHEN C.leaf_offset >1THEN max_length ELSE0END), 0) FROM sys.system_internals_partition_columns C WHERE cols.partition_id = C.partition_id AND C.leaf_null_bit < cols.leaf_null_bit ) +5AS[Column value Size] , syscolumns.length AS[Column Length] , CASEWHENSUBSTRING([nullBitMap], cols.leaf_null_bit, 1) =1THENNULLELSESUBSTRING(Rowlogcontents, ( SELECTTOP1ISNULL(SUM(CASEWHEN C.leaf_offset >1AND C.leaf_bit_position =0THEN max_length ELSE0END), 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) ENDAS hex_Value , [Slot ID] , 0FROM@DeletedRecords A INNERJOIN sys.allocation_units allocunits ON A.[AllocUnitId]= allocunits.[Allocation_Unit_Id]INNERJOIN sys.partitions partitions ON ( allocunits.type IN ( 1, 3 ) AND partitions.hobt_id = allocunits.container_id ) OR ( allocunits.type =2AND partitions.partition_id = allocunits.container_id ) INNERJOIN sys.system_internals_partition_columns cols ON cols.partition_id = partitions.partition_id LEFTOUTERJOIN syscolumns ON syscolumns.id = partitions.object_idAND syscolumns.colid = cols.partition_column_id WHERE leaf_offset >0ORDERBY nullbit DECLARE@BitColumnByteASINTSELECT@BitColumnByte=CONVERT(INT, CEILING(COUNT(*) /8.0)) FROM@ColumnNameAndDataWHERE[System_Type_id]=104; WITH N1 ( n ) AS ( SELECT1UNIONALLSELECT1 ), N2 ( n ) AS ( SELECT1FROM N1 AS X , N1 AS Y ), N3 ( n ) AS ( SELECT1FROM N2 AS X , N2 AS Y ), N4 ( n ) AS ( SELECT ROW_NUMBER() OVER ( ORDERBY X.n ) FROM N3 AS X , N3 AS Y ), CTE AS ( SELECT RowLogContents , [nullbit] , [BitMap]=CONVERT(VARBINARY(1), CONVERT(INT, SUBSTRING(( REPLACE(STUFF(( SELECT\',\'+ ( CASEWHEN[ID]=0THENCONVERT(NVARCHAR(1), ( SUBSTRING(hex_Value, n, 1) %2 )) ELSECONVERT(NVARCHAR(1), ( ( SUBSTRING(hex_Value, n, 1) /[Bitvalue] ) %2 )) END ) --as [nullBitMap]FROM N4 AS Nums JOIN@ColumnNameAndDataAS C ON n <=@BitColumnByteAND[System_Type_id]=104AND bitpos =0CROSSJOIN@bitTableWHERE C.[RowLogContents]= D.[RowLogContents]ORDERBY[RowLogContents] , n ASCFOR XML PATH(\'\') ), 1, 1, \'\'), \',\', \'\') ), bitpos +1, 1))) FROM@ColumnNameAndData D WHERE[System_Type_id]=104 ) UPDATE A SET[hex_Value]=[BitMap]FROM@ColumnNameAndData A INNERJOIN CTE B ON A.[RowLogContents]= B.[RowLogContents]AND A.[nullbit]= B.[nullbit]/**************Check for BLOB DATA TYPES******************************/DECLARE@FileidINTDECLARE@PageidINTDECLARE@SlotidINTDECLARE@CurrentLSNINTDECLARE@LinkIDINTDECLARE@ContextVARCHAR(50) DECLARE@ConsolidatedPageIDVARCHAR(MAX) DECLARE@LCX_TEXT_MIXVARBINARY(MAX) DECLARE@temppagedataTABLE ( [ParentObject] SYSNAME , [Object] SYSNAME , [Field] SYSNAME , [Value] SYSNAME ) DECLARE@pagedataTABLE ( [Page ID] SYSNAME , [File IDS]INT , [Page IDS]INT , [AllocUnitId]BIGINT , [ParentObject] SYSNAME , [Object] SYSNAME , [Field] SYSNAME , [Value] SYSNAME ) DECLARE@ModifiedRawDataTABLE ( [ID]INTIDENTITY(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]INTDEFAULT ( 0 ) , [Update]INT ) DECLARE Page_Data_Cursor CURSORFOR/*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*/SELECTLTRIM(RTRIM(REPLACE([Description], \'Deallocated\', \'\'))) AS[PAGE ID] , [Slot ID] , [AllocUnitId] , NULLAS[RowLog Contents 0] , NULLAS[RowLog Contents 0] , Context FROM sys.fn_dblog(NULL, NULL) WHERE AllocUnitId IN ( SELECT[Allocation_unit_id]FROM sys.allocation_units allocunits INNERJOIN sys.partitions partitions ON ( allocunits.type IN ( 1, 3 ) AND partitions.hobt_id = allocunits.container_id ) OR ( allocunits.type =2AND partitions.partition_id = allocunits.container_id ) WHEREobject_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 ( SELECTDISTINCT[TRANSACTION ID]FROM sys.fn_dblog(NULL, NULL) WHERE Context IN ( \'LCX_NULL\' ) AND Operation IN ( \'LOP_BEGIN_XACT\' ) AND[Transaction Name]=\'DELETE\'ANDCONVERT(NVARCHAR(11), [Begin Time]) BETWEEN@Date_FromAND@Date_To ) GROUPBY[Description] , [Slot ID] , [AllocUnitId] , Context UNIONSELECT[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 INNERJOIN sys.partitions partitions ON ( allocunits.type IN ( 1, 3 ) AND partitions.hobt_id = allocunits.container_id ) OR ( allocunits.type =2AND partitions.partition_id = allocunits.container_id ) WHEREobject_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 ( SELECTDISTINCT[TRANSACTION ID]FROM sys.fn_dblog(NULL, NULL) WHERE Context IN ( \'LCX_NULL\' ) AND Operation IN ( \'LOP_BEGIN_XACT\' ) AND[Transaction Name]=\'DELETE\'ANDCONVERT(NVARCHAR(11), [Begin Time]) BETWEEN@Date_FromAND@Date_To ) /****************************************/OPEN Page_Data_Cursor FETCHNEXTFROM Page_Data_Cursor INTO@ConsolidatedPageID, @Slotid, @AllocUnitID, @LCX_TEXT_MIX, @LinkID, @ContextWHILE@@FETCH_STATUS=0BEGINDECLARE@hex_pageidASVARCHAR(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 IDSET@hex_pageid=\'0x\'+SUBSTRING(@ConsolidatedPageID, CHARINDEX(\':\', @ConsolidatedPageID) +1, LEN(@ConsolidatedPageID)) ---Seperate the page IDSELECT@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 integerFROM ( SELECTCASESUBSTRING(@hex_pageid, 1, 2) WHEN\'0x\'THEN3ELSE0END ) AS t ( pos ) IF@Context=\'LCX_PFS\'BEGINDELETE@temppagedataINSERTINTO@temppagedataEXEC ( \'DBCC PAGE(\'+@DataBase_Name+\', \'+@fileid+\', \'+@pageid+\', 1) with tableresults,no_infomsgs;\' ); INSERTINTO@pagedataSELECT@ConsolidatedPageID , @fileid , @pageid , @AllocUnitID , [ParentObject] , [Object] , [Field] , [Value]FROM@temppagedataENDELSEIF@Context=\'LCX_TEXT_MIX\'BEGININSERTINTO@ModifiedRawDataSELECT@ConsolidatedPageID , @fileid , @pageid , @Slotid , @AllocUnitID , NULL , 0 , CONVERT(INT, CONVERT(VARBINARY, REVERSE(SUBSTRING(@LCX_TEXT_MIX, 11, 2)))) , @LCX_TEXT_MIX , @LinkID , 0ENDFETCHNEXTFROM Page_Data_Cursor INTO@ConsolidatedPageID, @Slotid, @AllocUnitID, @LCX_TEXT_MIX, @LinkID, @ContextENDCLOSE Page_Data_Cursor DEALLOCATE Page_Data_Cursor DECLARE@NewhexstringVARCHAR(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 formatINSERTINTO@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(( SELECTREPLACE(STUFF(( SELECTREPLACE(SUBSTRING([Value], CHARINDEX(\':\', [Value]) +1, CHARINDEX(\'†\', [Value]) -CHARINDEX(\':\', [Value])), \'†\', \'\') FROM@pagedata C WHERE B.[Page ID]= C.[Page ID]ANDSUBSTRING(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%\'ORDERBY\'0x\'+LEFT([Value], CHARINDEX(\':\', [Value]) -1) FOR XML PATH(\'\') ), 1, 1, \'\'), \'\', \'\') ), 1, 20000) AS[Value] , SUBSTRING(( SELECT\'0x\'+REPLACE(STUFF(( SELECTREPLACE(SUBSTRING([Value], CHARINDEX(\':\', [Value]) +1, CHARINDEX(\'†\', [Value]) -CHARINDEX(\':\', [Value])), \'†\', \'\') FROM@pagedata C WHERE B.[Page ID]= C.[Page ID]ANDSUBSTRING(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%\'ORDERBY\'0x\'+LEFT([Value], CHARINDEX(\':\', [Value]) -1) FOR XML PATH(\'\') ), 1, 1, \'\'), \'\', \'\') ), 7, 4) AS[Length]FROM@pagedata B WHERE[Object]LIKE\'%Memory Dump%\'GROUPBY[Page ID] , [FILE IDS] , [PAGE IDS] , [ParentObject] , [AllocUnitId]--,[Current LSN]ORDERBY[Slot ID]UPDATE@ModifiedRawDataSET[RowLog Len]=CONVERT(VARBINARY(8000), REVERSE(CAST(\'\'AS XML).value(\'xs:hexBinary(substring(sql:column("[RowLog Length]"),0))\', \'varbinary(Max)\'))) FROM@ModifiedRawDataWHERE[LINK ID]=0UPDATE@ModifiedRawDataSET[RowLog Contents 0]=CAST(\'\'AS XML).value(\'xs:hexBinary(substring(sql:column("[RowLog Contents 0_var]"),0))\', \'varbinary(Max)\') FROM@ModifiedRawDataWHERE[LINK ID]=0UPDATE B SET B.[RowLog Contents 0]= ( CASEWHEN A.[RowLog Contents 0]ISNOTNULLAND C.[RowLog Contents 0]ISNOTNULLTHEN A.[RowLog Contents 0]+ C.[RowLog Contents 0]WHEN A.[RowLog Contents 0]ISNULLAND C.[RowLog Contents 0]ISNOTNULLTHEN C.[RowLog Contents 0]WHEN A.[RowLog Contents 0]ISNOTNULLAND C.[RowLog Contents 0]ISNULLTHEN A.[RowLog Contents 0]END ) , B.[Update]=ISNULL(B.[Update], 0) +1FROM@ModifiedRawData B LEFTJOIN@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]LEFTJOIN@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]ISNOTNULLOR C.[RowLog Contents 0]ISNOTNULL ) UPDATE B SET B.[RowLog Contents 0]= ( CASEWHEN A.[RowLog Contents 0]ISNOTNULLAND C.[RowLog Contents 0]ISNOTNULLTHEN A.[RowLog Contents 0]+ C.[RowLog Contents 0]WHEN A.[RowLog Contents 0]ISNULLAND C.[RowLog Contents 0]ISNOTNULLTHEN C.[RowLog Contents 0]WHEN A.[RowLog Contents 0]ISNOTNULLAND C.[RowLog Contents 0]ISNULLTHEN A.[RowLog Contents 0]END ) --,B.[Update]=ISNULL(B.[Update],0)+1FROM@ModifiedRawData B LEFTJOIN@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]=0LEFTJOIN@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]=0WHERE ( A.[RowLog Contents 0]ISNOTNULLOR C.[RowLog Contents 0]ISNOTNULL ) UPDATE@ModifiedRawDataSET[RowLog Contents 0]= ( CASEWHEN[RowLog Len]>=8000THENSUBSTRING([RowLog Contents 0], 15, [RowLog Len]) WHEN[RowLog Len]<8000THENSUBSTRING([RowLog Contents 0], 15+6, CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([RowLog Contents 0], 15, 6))))) END ) FROM@ModifiedRawDataWHERE[LINK ID]=0UPDATE@ColumnNameAndDataSET[hex_Value]=[RowLog Contents 0]--,A.[Update]=A.[Update]+1FROM@ColumnNameAndData A INNERJOIN@ModifiedRawData B ONCONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value], 17, 4)))) =[PAGE IDS]ANDCONVERT(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]<>0UPDATE@ColumnNameAndDataSET[hex_Value]= ( CASEWHEN B.[RowLog Contents 0]ISNOTNULLAND C.[RowLog Contents 0]ISNOTNULLTHEN B.[RowLog Contents 0]+ C.[RowLog Contents 0]WHEN B.[RowLog Contents 0]ISNULLAND C.[RowLog Contents 0]ISNOTNULLTHEN C.[RowLog Contents 0]WHEN B.[RowLog Contents 0]ISNOTNULLAND C.[RowLog Contents 0]ISNULLTHEN B.[RowLog Contents 0]END ) --,A.[Update]=A.[Update]+1FROM@ColumnNameAndData A LEFTJOIN@ModifiedRawData B ONCONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value], 5, 4)))) = B.[PAGE IDS]AND B.[Link ID]=0LEFTJOIN@ModifiedRawData C ONCONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value], 17, 4)))) = C.[PAGE IDS]AND C.[Link ID]=0WHERE[System_Type_Id]IN ( 99, 167, 175, 231, 239, 241, 165, 98 ) AND ( B.[RowLog Contents 0]ISNOTNULLOR C.[RowLog Contents 0]ISNOTNULL ) UPDATE@ColumnNameAndDataSET[hex_Value]=[RowLog Contents 0]--,A.[Update]=A.[Update]+1FROM@ColumnNameAndData A INNERJOIN@ModifiedRawData B ONCONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value], 9, 4)))) =[PAGE IDS]ANDCONVERT(INT, SUBSTRING([hex_value], 3, 2)) =[Link ID]WHERE[System_Type_Id]IN ( 35, 34, 99 ) AND[Link ID]<>0UPDATE@ColumnNameAndDataSET[hex_Value]=[RowLog Contents 0]--,A.[Update]=A.[Update]+10FROM@ColumnNameAndData A INNERJOIN@ModifiedRawData B ONCONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value], 9, 4)))) =[PAGE IDS]WHERE[System_Type_Id]IN ( 35, 34, 99 ) AND[Link ID]=0UPDATE@ColumnNameAndDataSET[hex_Value]=[RowLog Contents 0]--,A.[Update]=A.[Update]+1FROM@ColumnNameAndData A INNERJOIN@ModifiedRawData B ONCONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value], 15, 4)))) =[PAGE IDS]WHERE[System_Type_Id]IN ( 35, 34, 99 ) AND[Link ID]=0UPDATE@ColumnNameAndDataSET[hex_value]=0xFFFE+SUBSTRING([hex_value], 9, LEN([hex_value])) --,[Update]=[Update]+1WHERE[system_type_id]=241CREATETABLE[#temp_Data] ( [FieldName]VARCHAR(MAX) , [FieldValue]NVARCHAR(MAX) , [Rowlogcontents]VARBINARY(8000) , [Row ID]INT ) INSERTINTO #temp_Data SELECT NAME , CASEWHEN system_type_id IN ( 231, 239 ) THENLTRIM(RTRIM(CONVERT(NVARCHAR(MAX), hex_Value))) --NVARCHAR ,NCHARWHEN system_type_id IN ( 167, 175 ) THENLTRIM(RTRIM(CONVERT(VARCHAR(MAX), hex_Value))) --VARCHAR,CHARWHEN system_type_id IN ( 35 ) THENLTRIM(RTRIM(CONVERT(VARCHAR(MAX), hex_Value))) --TextWHEN system_type_id IN ( 99 ) THENLTRIM(RTRIM(CONVERT(NVARCHAR(MAX), hex_Value))) --nText WHEN system_type_id =48THENCONVERT(VARCHAR(MAX), CONVERT(TINYINT, CONVERT(BINARY(1), REVERSE(hex_Value)))) --TINY INTEGERWHEN system_type_id =52THENCONVERT(VARCHAR(MAX), CONVERT(SMALLINT, CONVERT(BINARY(2), REVERSE(hex_Value)))) --SMALL INTEGERWHEN system_type_id =56THENCONVERT(VARCHAR(MAX), CONVERT(INT, CONVERT(BINARY(4), REVERSE(hex_Value)))) -- INTEGERWHEN system_type_id =127THENCONVERT(VARCHAR(MAX), CONVERT(BIGINT, CONVERT(BINARY(8), REVERSE(hex_Value))))-- BIG INTEGERWHEN system_type_id =61THENCONVERT(VARCHAR(MAX), CONVERT(DATETIME, CONVERT(VARBINARY(8000), REVERSE(hex_Value))), 100) --DATETIMEWHEN system_type_id =58THENCONVERT(VARCHAR(MAX), CONVERT(SMALLDATETIME, CONVERT(VARBINARY(8000), REVERSE(hex_Value))), 100) --SMALL DATETIMEWHEN system_type_id =108THENCONVERT(VARCHAR(MAX), CONVERT(NUMERIC(38, 20), CONVERT(VARBINARY, CONVERT(VARBINARY(1), xprec) +CONVERT(VARBINARY(1), xscale)) +CONVERT(VARBINARY(1), 0) + hex_Value)) --- NUMERICWHEN system_type_id =106THENCONVERT(VARCHAR(MAX), CONVERT(DECIMAL(38, 20), CONVERT(VARBINARY, CONVERT(VARBINARY(1), xprec) +CONVERT(VARBINARY(1), xscale)) +CONVERT(VARBINARY(1), 0) + hex_Value)) --- DECIMALWHEN system_type_id IN ( 60, 122 ) THENCONVERT(VARCHAR(MAX), CONVERT(MONEY, CONVERT(VARBINARY(8000), REVERSE(hex_Value))), 2) --MONEY,SMALLMONEYWHEN system_type_id =104THENCONVERT(VARCHAR(MAX), CONVERT (BIT, CONVERT(BINARY(1), hex_Value) %2)) -- BITWHEN system_type_id =62THENRTRIM(LTRIM(STR(CONVERT(FLOAT, SIGN(CAST(CONVERT(VARBINARY(8000), REVERSE(hex_Value)) ASBIGINT)) * ( 1.0+ ( CAST(CONVERT(VARBINARY(8000), REVERSE(hex_Value)) ASBIGINT) &0x000FFFFFFFFFFFFF ) *POWER(CAST(2ASFLOAT), -52) ) *POWER(CAST(2ASFLOAT), ( ( CAST(CONVERT(VARBINARY(8000), REVERSE(hex_Value)) ASBIGINT) &0x7ff0000000000000 ) /EXP(52*LOG(2)) -1023 ))), 53, LEN(hex_Value)))) --- FLOATWHEN system_type_id =59THENLEFT(LTRIM(STR(CAST(SIGN(CAST(CONVERT(VARBINARY(8000), REVERSE(hex_Value)) ASBIGINT)) * ( 1.0+ ( CAST(CONVERT(VARBINARY(8000), REVERSE(hex_Value)) ASBIGINT) &0x007FFFFF ) *POWER(CAST(2ASREAL), -23) ) *POWER(CAST(2ASREAL), ( ( ( CAST(CONVERT(VARBINARY(8000), REVERSE(hex_Value)) ASINT) ) &0x7f800000 ) /EXP(23*LOG(2)) -127 )) ASREAL), 23, 23)), 8) --RealWHEN system_type_id IN ( 165, 173 ) THEN ( CASEWHENCHARINDEX(0x, CAST(\'\'AS XML).value(\'xs:hexBinary(sql:column("hex_Value"))\', \'VARBINARY(8000)\')) =0THEN\'0x\'ELSE\'\'END ) +CAST(\'\'AS XML).value(\'xs:hexBinary(sql:colu以上是关于转 --- 恢复误删数据的主要内容,如果未能解决你的问题,请参考以下文章