----创建存储过程

  1. CREATE PROCEDURE Recover_Deleted_Data_Proc
  2. @Database_Name NVARCHAR(MAX) ,
  3. @SchemaName_n_TableName NVARCHAR(MAX) ,
  4. @Date_From DATETIME = '1900/01/01' ,
  5. @Date_To DATETIME = '9999/12/31'
  6. AS
  7. DECLARE @RowLogContents VARBINARY()
  8. DECLARE @TransactionID NVARCHAR(MAX)
  9. DECLARE @AllocUnitID BIGINT
  10. DECLARE @AllocUnitName NVARCHAR(MAX)
  11. DECLARE @SQL NVARCHAR(MAX)
  12. DECLARE @Compatibility_Level INT
  13.  
  14. SELECT @Compatibility_Level = dtb.compatibility_level
  15. FROM master.sys.databases AS dtb
  16. WHERE dtb.name = @Database_Name
  17.  
  18. IF ISNULL(@Compatibility_Level, ) <=
  19. BEGIN
  20. RAISERROR('The compatibility level should be equal to or greater SQL SERVER 2005 (90)',,)
  21. RETURN
  22. END
  23.  
  24. IF ( SELECT COUNT(*)
  25. FROM INFORMATION_SCHEMA.TABLES
  26. WHERE [TABLE_SCHEMA] + '.' + [TABLE_NAME] = @SchemaName_n_TableName
  27. ) =
  28. BEGIN
  29. RAISERROR('Could not found the table in the defined database',,)
  30. RETURN
  31. END
  32.  
  33. DECLARE @bitTable TABLE
  34. (
  35. [ID] INT ,
  36. [Bitvalue] INT
  37. )
  38. --Create table to set the bit position of one byte.
  39.  
  40. INSERT INTO @bitTable
  41. SELECT ,
  42.  
  43. UNION ALL
  44. SELECT ,
  45.  
  46. UNION ALL
  47. SELECT ,
  48.  
  49. UNION ALL
  50. SELECT ,
  51.  
  52. UNION ALL
  53. SELECT ,
  54.  
  55. UNION ALL
  56. SELECT ,
  57.  
  58. UNION ALL
  59. SELECT ,
  60.  
  61. UNION ALL
  62. SELECT ,
  63.  
  64. --Create table to collect the row data.
  65. DECLARE @DeletedRecords TABLE
  66. (
  67. [Row ID] INT IDENTITY(, ) ,
  68. [RowLogContents] VARBINARY() ,
  69. [AllocUnitID] BIGINT ,
  70. [Transaction ID] NVARCHAR(MAX) ,
  71. [FixedLengthData] SMALLINT ,
  72. [TotalNoOfCols] SMALLINT ,
  73. [NullBitMapLength] SMALLINT ,
  74. [NullBytes] VARBINARY() ,
  75. [TotalNoofVarCols] SMALLINT ,
  76. [ColumnOffsetArray] VARBINARY() ,
  77. [VarColumnStart] SMALLINT ,
  78. [Slot ID] INT ,
  79. [NullBitMap] VARCHAR(MAX)
  80. )
  81. --Create a common table expression to get all the row data plus how many bytes we have for each row.
  82. ;
  83. WITH RowData
  84. AS ( SELECT [RowLog Contents ] AS [RowLogContents] ,
  85. [AllocUnitID] AS [AllocUnitID] ,
  86. [Transaction ID] AS [Transaction ID]
  87.  
  88. --[Fixed Length Data] = Substring (RowLog content , Status Bit A+ Status Bit B + , bytes)
  89. ,
  90. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  91. + , )))) AS [FixedLengthData] --@FixedLengthData
  92.  
  93. -- [TotalnoOfCols] = Substring (RowLog content , [Fixed Length Data] + , bytes)
  94. ,
  95. CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  96. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  97. + , )))) + ,
  98. )))) AS [TotalNoOfCols]
  99.  
  100. --[NullBitMapLength]=ceiling([Total No of Columns] /8.0)
  101. ,
  102. CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  103. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  104. + , )))) + ,
  105. )))) / 8.0)) AS [NullBitMapLength]
  106.  
  107. --[Null Bytes] = Substring (RowLog content , Status Bit A+ Status Bit B + [Fixed Length Data] +, [NullBitMapLength] )
  108. ,
  109. SUBSTRING([RowLog Contents ],
  110. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  111. + , )))) + ,
  112. CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  113. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  114. + , )))) + ,
  115. )))) / 8.0))) AS [NullBytes]
  116.  
  117. --[TotalNoofVarCols] = Substring (RowLog content , Status Bit A+ Status Bit B + [Fixed Length Data] +, [Null Bitmap length] + )
  118. ,
  119. ( CASE WHEN SUBSTRING([RowLog Contents ], , ) IN (
  120. 0x10, 0x30, 0x70 )
  121. THEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  122. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  123. + , )))) +
  124. + CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  125. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  126. + , )))) + ,
  127. )))) / 8.0)), ))))
  128. ELSE NULL
  129. END ) AS [TotalNoofVarCols]
  130.  
  131. --[ColumnOffsetArray]= Substring (RowLog content , Status Bit A+ Status Bit B + [Fixed Length Data] +, [Null Bitmap length] + , [TotalNoofVarCols]* )
  132. ,
  133. ( CASE WHEN SUBSTRING([RowLog Contents ], , ) IN (
  134. 0x10, 0x30, 0x70 )
  135. THEN SUBSTRING([RowLog Contents ],
  136. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  137. + , )))) +
  138. + CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  139. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  140. + , )))) + ,
  141. )))) / 8.0))
  142. + ,
  143. ( CASE WHEN SUBSTRING([RowLog Contents ],
  144. , ) IN ( 0x10,
  145. 0x30, 0x70 )
  146. THEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  147. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  148. + , )))) +
  149. + CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  150. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  151. + , )))) + ,
  152. )))) / 8.0)), ))))
  153. ELSE NULL
  154. END ) * )
  155. ELSE NULL
  156. END ) AS [ColumnOffsetArray]
  157.  
  158. -- Variable column Start = Status Bit A+ Status Bit B + [Fixed Length Data] + [Null Bitmap length] + +([TotalNoofVarCols]*)
  159. ,
  160. CASE WHEN SUBSTRING([RowLog Contents ], , ) IN (
  161. 0x10, 0x30, 0x70 )
  162. THEN ( CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  163. + , )))) +
  164. + CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  165. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  166. + , )))) + ,
  167. )))) / 8.0))
  168. + ( ( CASE WHEN SUBSTRING([RowLog Contents ],
  169. , ) IN ( 0x10,
  170. 0x30, 0x70 )
  171. THEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  172. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  173. + , )))) +
  174. + CONVERT(INT, CEILING(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  175. CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(SUBSTRING([RowLog Contents ],
  176. + , )))) + ,
  177. )))) / 8.0)), ))))
  178. ELSE NULL
  179. END ) * ) )
  180. ELSE NULL
  181. END AS [VarColumnStart] ,
  182. [Slot ID]
  183. FROM sys.fn_dblog(NULL, NULL)
  184. WHERE AllocUnitId IN (
  185. SELECT [Allocation_unit_id]
  186. FROM sys.allocation_units allocunits
  187. INNER JOIN sys.partitions partitions ON ( allocunits.type IN (
  188. , )
  189. AND partitions.hobt_id = allocunits.container_id
  190. )
  191. OR ( allocunits.type =
  192. AND partitions.partition_id = allocunits.container_id
  193. )
  194. WHERE object_id = OBJECT_ID(''
  195. + @SchemaName_n_TableName
  196. + '') )
  197. AND Context IN ( 'LCX_MARK_AS_GHOST', 'LCX_HEAP' )
  198. AND Operation IN ( 'LOP_DELETE_ROWS' )
  199. AND SUBSTRING([RowLog Contents ], , ) IN ( 0x10,
  200. 0x30, 0x70 )
  201.  
  202. /*Use this subquery to filter the date*/
  203. AND [TRANSACTION ID] IN (
  204. SELECT DISTINCT
  205. [TRANSACTION ID]
  206. FROM sys.fn_dblog(NULL, NULL)
  207. WHERE Context IN ( 'LCX_NULL' )
  208. AND Operation IN ( 'LOP_BEGIN_XACT' )
  209. AND [Transaction Name] IN ( 'DELETE',
  210. 'user_transaction' )
  211. AND CONVERT(NVARCHAR(), [Begin Time]) BETWEEN @Date_From
  212. AND
  213. @Date_To )
  214. ),
  215.  
  216. --Use this technique to repeate the row till the no of bytes of the row.
  217. N1 ( n )
  218. AS ( SELECT
  219. UNION ALL
  220. SELECT
  221. ),
  222. N2 ( n )
  223. AS ( SELECT
  224. FROM N1 AS X ,
  225. N1 AS Y
  226. ),
  227. N3 ( n )
  228. AS ( SELECT
  229. FROM N2 AS X ,
  230. N2 AS Y
  231. ),
  232. N4 ( n )
  233. AS ( SELECT ROW_NUMBER() OVER ( ORDER BY X.n )
  234. FROM N3 AS X ,
  235. N3 AS Y
  236. )
  237. INSERT INTO @DeletedRecords
  238. SELECT RowLogContents ,
  239. [AllocUnitID] ,
  240. [Transaction ID] ,
  241. [FixedLengthData] ,
  242. [TotalNoOfCols] ,
  243. [NullBitMapLength] ,
  244. [NullBytes] ,
  245. [TotalNoofVarCols] ,
  246. [ColumnOffsetArray] ,
  247. [VarColumnStart] ,
  248. [Slot ID]
  249. ---Get the Null value against each column ( means null zero means not null)
  250. ,
  251. [NullBitMap] = ( REPLACE(STUFF(( SELECT
  252. ','
  253. + ( CASE
  254. WHEN [ID] =
  255. THEN CONVERT(NVARCHAR(), ( SUBSTRING(NullBytes,
  256. n, ) % ))
  257. ELSE CONVERT(NVARCHAR(), ( ( SUBSTRING(NullBytes,
  258. n, )
  259. / [Bitvalue] )
  260. % ))
  261. END ) --as [nullBitMap]
  262. FROM N4 AS Nums
  263. JOIN RowData AS C ON n <= NullBitMapLength
  264. CROSS JOIN @bitTable
  265. WHERE
  266. C.[RowLogContents] = D.[RowLogContents]
  267. ORDER BY [RowLogContents] ,
  268. n ASC
  269. FOR
  270. XML PATH('')
  271. ), , , ''), ',', '') )
  272. FROM RowData D
  273.  
  274. IF ( SELECT COUNT(*)
  275. FROM @DeletedRecords
  276. ) =
  277. BEGIN
  278. RAISERROR('There is no data in the log as per the search criteria',,)
  279. RETURN
  280. END
  281.  
  282. DECLARE @ColumnNameAndData TABLE
  283. (
  284. [Row ID] INT ,
  285. [Rowlogcontents] VARBINARY(MAX) ,
  286. [NAME] SYSNAME ,
  287. [nullbit] SMALLINT ,
  288. [leaf_offset] SMALLINT ,
  289. [length] SMALLINT ,
  290. [system_type_id] TINYINT ,
  291. [bitpos] TINYINT ,
  292. [xprec] TINYINT ,
  293. [xscale] TINYINT ,
  294. [is_null] INT ,
  295. [Column value Size] INT ,
  296. [Column Length] INT ,
  297. [hex_Value] VARBINARY(MAX) ,
  298. [Slot ID] INT ,
  299. [Update] INT
  300. )
  301.  
  302. --Create common table expression and join it with the rowdata table
  303. -- to get each column details
  304. /*This part is for variable data columns*/
  305. --@RowLogContents,
  306. --(col.columnOffValue - col.columnLength) + ,
  307. --col.columnLength
  308. --)
  309. INSERT INTO @ColumnNameAndData
  310. SELECT [Row ID] ,
  311. Rowlogcontents ,
  312. NAME ,
  313. cols.leaf_null_bit AS nullbit ,
  314. leaf_offset ,
  315. ISNULL(syscolumns.length, cols.max_length) AS [length] ,
  316. cols.system_type_id ,
  317. cols.leaf_bit_position AS bitpos ,
  318. ISNULL(syscolumns.xprec, cols.precision) AS xprec ,
  319. ISNULL(syscolumns.xscale, cols.scale) AS xscale ,
  320. SUBSTRING([nullBitMap], cols.leaf_null_bit, ) AS is_null ,
  321. ( CASE WHEN leaf_offset <
  322. AND SUBSTRING([nullBitMap], cols.leaf_null_bit,
  323. ) =
  324. THEN ( CASE WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  325. (
  326. * leaf_offset
  327. * - ) - , )))) >
  328. THEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  329. (
  330. * leaf_offset
  331. * - ) - , ))))
  332. - POWER(, )
  333. ELSE CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  334. (
  335. * leaf_offset
  336. * - ) - , ))))
  337. END )
  338. END ) AS [Column value Size] ,
  339. ( CASE WHEN leaf_offset <
  340. AND SUBSTRING([nullBitMap], cols.leaf_null_bit,
  341. ) =
  342. THEN ( CASE WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  343. (
  344. * leaf_offset
  345. * - ) - , )))) >
  346. AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  347. (
  348. * ( ( leaf_offset
  349. * - ) - ) )
  350. - , )))), ),
  351. [varColumnStart]) <
  352. THEN ( CASE WHEN [System_type_id] IN (
  353. , , ) THEN
  354. ELSE
  355. END )
  356. WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  357. (
  358. * leaf_offset
  359. * - ) - , )))) >
  360. AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  361. (
  362. * ( ( leaf_offset
  363. * - ) - ) )
  364. - , )))), ),
  365. [varColumnStart]) >
  366. THEN ( CASE WHEN [System_type_id] IN (
  367. , , ) THEN
  368. ELSE
  369. END ) --
  370. WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  371. (
  372. * leaf_offset
  373. * - ) - , )))) <
  374. AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  375. (
  376. * ( ( leaf_offset
  377. * - ) - ) )
  378. - , )))), ),
  379. [varColumnStart]) <
  380. THEN ( CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  381. (
  382. * leaf_offset
  383. * - ) - , ))))
  384. - ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  385. (
  386. * ( ( leaf_offset
  387. * - ) - ) )
  388. - , )))), ),
  389. [varColumnStart]) )
  390. WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  391. (
  392. * leaf_offset
  393. * - ) - , )))) <
  394. AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  395. (
  396. * ( ( leaf_offset
  397. * - ) - ) )
  398. - , )))), ),
  399. [varColumnStart]) >
  400. THEN POWER(, )
  401. + CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  402. (
  403. * leaf_offset
  404. * - ) - , ))))
  405. - ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  406. (
  407. * ( ( leaf_offset
  408. * - ) - ) )
  409. - , )))), ),
  410. [varColumnStart])
  411. END )
  412. END ) AS [Column Length] ,
  413. ( CASE WHEN SUBSTRING([nullBitMap], cols.leaf_null_bit, ) =
  414. THEN NULL
  415. ELSE SUBSTRING(Rowlogcontents,
  416. ( ( CASE WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  417. (
  418. * leaf_offset
  419. * - ) - , )))) >
  420. THEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  421. (
  422. * leaf_offset
  423. * - ) - , ))))
  424. - POWER(, )
  425. ELSE CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  426. (
  427. * leaf_offset
  428. * - ) - , ))))
  429. END )
  430. - ( CASE WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  431. (
  432. * leaf_offset
  433. * - ) - , )))) >
  434. AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  435. (
  436. * ( ( leaf_offset
  437. * - ) - ) )
  438. - , )))), ),
  439. [varColumnStart]) <
  440. THEN ( CASE
  441. WHEN [System_type_id] IN (
  442. , , )
  443. THEN
  444. ELSE
  445. END ) --
  446. WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  447. (
  448. * leaf_offset
  449. * - ) - , )))) >
  450. AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  451. (
  452. * ( ( leaf_offset
  453. * - ) - ) )
  454. - , )))), ),
  455. [varColumnStart]) >
  456. THEN ( CASE
  457. WHEN [System_type_id] IN (
  458. , , )
  459. THEN
  460. ELSE
  461. END ) --
  462. WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  463. (
  464. * leaf_offset
  465. * - ) - , )))) <
  466. AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  467. (
  468. * ( ( leaf_offset
  469. * - ) - ) )
  470. - , )))), ),
  471. [varColumnStart]) <
  472. THEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  473. (
  474. * leaf_offset
  475. * - ) - , ))))
  476. - ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  477. (
  478. * ( ( leaf_offset
  479. * - ) - ) )
  480. - , )))), ),
  481. [varColumnStart])
  482. WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  483. (
  484. * leaf_offset
  485. * - ) - , )))) <
  486. AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  487. (
  488. * ( ( leaf_offset
  489. * - ) - ) )
  490. - , )))), ),
  491. [varColumnStart]) >
  492. THEN POWER(, )
  493. + CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  494. (
  495. * leaf_offset
  496. * - ) - , ))))
  497. - ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  498. (
  499. * ( ( leaf_offset
  500. * - ) - ) )
  501. - , )))), ),
  502. [varColumnStart])
  503. END ) ) + ,
  504. ( CASE WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  505. (
  506. * leaf_offset
  507. * - ) - , )))) >
  508. AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  509. (
  510. * ( ( leaf_offset
  511. * - ) - ) )
  512. - , )))), ),
  513. [varColumnStart]) <
  514. THEN ( CASE WHEN [System_type_id] IN (
  515. , , )
  516. THEN
  517. ELSE
  518. END ) --
  519. WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  520. (
  521. * leaf_offset
  522. * - ) - , )))) >
  523. AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  524. (
  525. * ( ( leaf_offset
  526. * - ) - ) )
  527. - , )))), ),
  528. [varColumnStart]) >
  529. THEN ( CASE WHEN [System_type_id] IN (
  530. , , )
  531. THEN
  532. ELSE
  533. END ) --
  534. WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  535. (
  536. * leaf_offset
  537. * - ) - , )))) <
  538. AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  539. (
  540. * ( ( leaf_offset
  541. * - ) - ) )
  542. - , )))), ),
  543. [varColumnStart]) <
  544. THEN ABS(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  545. (
  546. * leaf_offset
  547. * - ) - , ))))
  548. - ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  549. (
  550. * ( ( leaf_offset
  551. * - ) - ) )
  552. - , )))), ),
  553. [varColumnStart]))
  554. WHEN CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  555. (
  556. * leaf_offset
  557. * - ) - , )))) <
  558. AND ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  559. (
  560. * ( ( leaf_offset
  561. * - ) - ) )
  562. - , )))), ),
  563. [varColumnStart]) >
  564. THEN POWER(, )
  565. + CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  566. (
  567. * leaf_offset
  568. * - ) - , ))))
  569. - ISNULL(NULLIF(CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING([ColumnOffsetArray],
  570. (
  571. * ( ( leaf_offset
  572. * - ) - ) )
  573. - , )))), ),
  574. [varColumnStart])
  575. END ))
  576. END ) AS hex_Value ,
  577. [Slot ID] ,
  578.  
  579. FROM @DeletedRecords A
  580. INNER JOIN sys.allocation_units allocunits ON A.[AllocUnitId] = allocunits.[Allocation_Unit_Id]
  581. INNER JOIN sys.partitions partitions ON ( allocunits.type IN (
  582. , )
  583. AND partitions.hobt_id = allocunits.container_id
  584. )
  585. OR ( allocunits.type =
  586. AND partitions.partition_id = allocunits.container_id
  587. )
  588. INNER JOIN sys.system_internals_partition_columns cols ON cols.partition_id = partitions.partition_id
  589. LEFT OUTER JOIN syscolumns ON syscolumns.id = partitions.object_id
  590. AND syscolumns.colid = cols.partition_column_id
  591. WHERE leaf_offset <
  592. UNION
  593. /*This part is for fixed data columns*/
  594. SELECT [Row ID] ,
  595. Rowlogcontents ,
  596. NAME ,
  597. cols.leaf_null_bit AS nullbit ,
  598. leaf_offset ,
  599. ISNULL(syscolumns.length, cols.max_length) AS [length] ,
  600. cols.system_type_id ,
  601. cols.leaf_bit_position AS bitpos ,
  602. ISNULL(syscolumns.xprec, cols.precision) AS xprec ,
  603. ISNULL(syscolumns.xscale, cols.scale) AS xscale ,
  604. SUBSTRING([nullBitMap], cols.leaf_null_bit, ) AS is_null ,
  605. ( SELECT TOP
  606. ISNULL(SUM(CASE WHEN C.leaf_offset >
  607. THEN max_length
  608. ELSE
  609. END), )
  610. FROM sys.system_internals_partition_columns C
  611. WHERE cols.partition_id = C.partition_id
  612. AND C.leaf_null_bit < cols.leaf_null_bit
  613. ) + AS [Column value Size] ,
  614. syscolumns.length AS [Column Length] ,
  615. CASE WHEN SUBSTRING([nullBitMap], cols.leaf_null_bit, ) =
  616. THEN NULL
  617. ELSE SUBSTRING(Rowlogcontents,
  618. ( SELECT TOP
  619. ISNULL(SUM(CASE
  620. WHEN C.leaf_offset >
  621. AND C.leaf_bit_position =
  622. THEN max_length
  623. ELSE
  624. END), )
  625. FROM sys.system_internals_partition_columns C
  626. WHERE cols.partition_id = C.partition_id
  627. AND C.leaf_null_bit < cols.leaf_null_bit
  628. ) + , syscolumns.length)
  629. END AS hex_Value ,
  630. [Slot ID] ,
  631.  
  632. FROM @DeletedRecords A
  633. INNER JOIN sys.allocation_units allocunits ON A.[AllocUnitId] = allocunits.[Allocation_Unit_Id]
  634. INNER JOIN sys.partitions partitions ON ( allocunits.type IN (
  635. , )
  636. AND partitions.hobt_id = allocunits.container_id
  637. )
  638. OR ( allocunits.type =
  639. AND partitions.partition_id = allocunits.container_id
  640. )
  641. INNER JOIN sys.system_internals_partition_columns cols ON cols.partition_id = partitions.partition_id
  642. LEFT OUTER JOIN syscolumns ON syscolumns.id = partitions.object_id
  643. AND syscolumns.colid = cols.partition_column_id
  644. WHERE leaf_offset >
  645. ORDER BY nullbit
  646.  
  647. DECLARE @BitColumnByte AS INT
  648. SELECT @BitColumnByte = CONVERT(INT, CEILING(COUNT(*) / 8.0))
  649. FROM @ColumnNameAndData
  650. WHERE [System_Type_id] = ;
  651. WITH N1 ( n )
  652. AS ( SELECT
  653. UNION ALL
  654. SELECT
  655. ),
  656. N2 ( n )
  657. AS ( SELECT
  658. FROM N1 AS X ,
  659. N1 AS Y
  660. ),
  661. N3 ( n )
  662. AS ( SELECT
  663. FROM N2 AS X ,
  664. N2 AS Y
  665. ),
  666. N4 ( n )
  667. AS ( SELECT ROW_NUMBER() OVER ( ORDER BY X.n )
  668. FROM N3 AS X ,
  669. N3 AS Y
  670. ),
  671. CTE
  672. AS ( SELECT RowLogContents ,
  673. [nullbit] ,
  674. [BitMap] = CONVERT(VARBINARY(), CONVERT(INT, SUBSTRING(( REPLACE(STUFF(( SELECT
  675. ','
  676. + ( CASE
  677. WHEN [ID] =
  678. THEN CONVERT(NVARCHAR(), ( SUBSTRING(hex_Value,
  679. n, ) % ))
  680. ELSE CONVERT(NVARCHAR(), ( ( SUBSTRING(hex_Value,
  681. n, )
  682. / [Bitvalue] )
  683. % ))
  684. END ) --as [nullBitMap]
  685. FROM
  686. N4 AS Nums
  687. JOIN @ColumnNameAndData
  688. AS C ON n <= @BitColumnByte
  689. AND [System_Type_id] =
  690. AND bitpos =
  691. CROSS JOIN @bitTable
  692. WHERE
  693. C.[RowLogContents] = D.[RowLogContents]
  694. ORDER BY [RowLogContents] ,
  695. n ASC
  696. FOR
  697. XML
  698. PATH('')
  699. ), , , ''),
  700. ',', '') ),
  701. bitpos + , )))
  702. FROM @ColumnNameAndData D
  703. WHERE [System_Type_id] =
  704. )
  705. UPDATE A
  706. SET [hex_Value] = [BitMap]
  707. FROM @ColumnNameAndData A
  708. INNER JOIN CTE B ON A.[RowLogContents] = B.[RowLogContents]
  709. AND A.[nullbit] = B.[nullbit]
  710.  
  711. /**************Check for BLOB DATA TYPES******************************/
  712. DECLARE @Fileid INT
  713. DECLARE @Pageid INT
  714. DECLARE @Slotid INT
  715. DECLARE @CurrentLSN INT
  716. DECLARE @LinkID INT
  717. DECLARE @Context VARCHAR()
  718. DECLARE @ConsolidatedPageID VARCHAR(MAX)
  719. DECLARE @LCX_TEXT_MIX VARBINARY(MAX)
  720.  
  721. DECLARE @temppagedata TABLE
  722. (
  723. [ParentObject] SYSNAME ,
  724. [Object] SYSNAME ,
  725. [Field] SYSNAME ,
  726. [Value] SYSNAME
  727. )
  728.  
  729. DECLARE @pagedata TABLE
  730. (
  731. [Page ID] SYSNAME ,
  732. [File IDS] INT ,
  733. [Page IDS] INT ,
  734. [AllocUnitId] BIGINT ,
  735. [ParentObject] SYSNAME ,
  736. [Object] SYSNAME ,
  737. [Field] SYSNAME ,
  738. [Value] SYSNAME
  739. )
  740.  
  741. DECLARE @ModifiedRawData TABLE
  742. (
  743. [ID] INT IDENTITY(, ) ,
  744. [PAGE ID] VARCHAR(MAX) ,
  745. [FILE IDS] INT ,
  746. [PAGE IDS] INT ,
  747. [Slot ID] INT ,
  748. [AllocUnitId] BIGINT ,
  749. [RowLog Contents 0_var] VARCHAR(MAX) ,
  750. [RowLog Length] VARCHAR() ,
  751. [RowLog Len] INT ,
  752. [RowLog Contents ] VARBINARY(MAX) ,
  753. [Link ID] INT DEFAULT ( ) ,
  754. [Update] INT
  755. )
  756.  
  757. DECLARE Page_Data_Cursor CURSOR
  758. FOR
  759. /*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*/
  760. SELECT LTRIM(RTRIM(REPLACE([Description], 'Deallocated', ''))) AS [PAGE ID] ,
  761. [Slot ID] ,
  762. [AllocUnitId] ,
  763. NULL AS [RowLog Contents ] ,
  764. NULL AS [RowLog Contents ] ,
  765. Context
  766. FROM sys.fn_dblog(NULL, NULL)
  767. WHERE AllocUnitId IN (
  768. SELECT [Allocation_unit_id]
  769. FROM sys.allocation_units allocunits
  770. INNER JOIN sys.partitions partitions ON ( allocunits.type IN (
  771. , )
  772. AND partitions.hobt_id = allocunits.container_id
  773. )
  774. OR ( allocunits.type =
  775. AND partitions.partition_id = allocunits.container_id
  776. )
  777. WHERE object_id = OBJECT_ID('' + @SchemaName_n_TableName
  778. + '') )
  779. AND Operation IN ( 'LOP_MODIFY_ROW' )
  780. AND [Context] IN ( 'LCX_PFS' )
  781. AND Description LIKE '%Deallocated%'
  782. /*Use this subquery to filter the date*/
  783. AND [TRANSACTION ID] IN (
  784. SELECT DISTINCT
  785. [TRANSACTION ID]
  786. FROM sys.fn_dblog(NULL, NULL)
  787. WHERE Context IN ( 'LCX_NULL' )
  788. AND Operation IN ( 'LOP_BEGIN_XACT' )
  789. AND [Transaction Name] = 'DELETE'
  790. AND CONVERT(NVARCHAR(), [Begin Time]) BETWEEN @Date_From
  791. AND
  792. @Date_To )
  793. GROUP BY [Description] ,
  794. [Slot ID] ,
  795. [AllocUnitId] ,
  796. Context
  797. UNION
  798. SELECT [PAGE ID] ,
  799. [Slot ID] ,
  800. [AllocUnitId] ,
  801. SUBSTRING([RowLog Contents ], ,
  802. LEN([RowLog Contents ])) AS [RowLog Contents ] ,
  803. CONVERT(INT, SUBSTRING([RowLog Contents ], , )) ,
  804. Context --,CAST(RIGHT([Current LSN],) AS INT) AS [Current LSN]
  805. FROM sys.fn_dblog(NULL, NULL)
  806. WHERE AllocUnitId IN (
  807. SELECT [Allocation_unit_id]
  808. FROM sys.allocation_units allocunits
  809. INNER JOIN sys.partitions partitions ON ( allocunits.type IN (
  810. , )
  811. AND partitions.hobt_id = allocunits.container_id
  812. )
  813. OR ( allocunits.type =
  814. AND partitions.partition_id = allocunits.container_id
  815. )
  816. WHERE object_id = OBJECT_ID('' + @SchemaName_n_TableName
  817. + '') )
  818. AND Context IN ( 'LCX_TEXT_MIX' )
  819. AND Operation IN ( 'LOP_DELETE_ROWS' )
  820. /*Use this subquery to filter the date*/
  821. AND [TRANSACTION ID] IN (
  822. SELECT DISTINCT
  823. [TRANSACTION ID]
  824. FROM sys.fn_dblog(NULL, NULL)
  825. WHERE Context IN ( 'LCX_NULL' )
  826. AND Operation IN ( 'LOP_BEGIN_XACT' )
  827. AND [Transaction Name] = 'DELETE'
  828. AND CONVERT(NVARCHAR(), [Begin Time]) BETWEEN @Date_From
  829. AND
  830. @Date_To )
  831.  
  832. /****************************************/
  833.  
  834. OPEN Page_Data_Cursor
  835.  
  836. FETCH NEXT FROM Page_Data_Cursor INTO @ConsolidatedPageID, @Slotid,
  837. @AllocUnitID, @LCX_TEXT_MIX, @LinkID, @Context
  838.  
  839. WHILE @@FETCH_STATUS =
  840. BEGIN
  841. DECLARE @hex_pageid AS VARCHAR(MAX)
  842. /*Page ID contains File Number and page number It looks like 0001:00000130.
  843. In this example 0001 is file Number & 00000130 is Page Number & These numbers are in Hex format*/
  844. SET @Fileid = SUBSTRING(@ConsolidatedPageID, ,
  845. CHARINDEX(':', @ConsolidatedPageID)) -- Seperate File ID from Page ID
  846.  
  847. SET @hex_pageid = '0x' + SUBSTRING(@ConsolidatedPageID,
  848. CHARINDEX(':',
  849. @ConsolidatedPageID)
  850. + , LEN(@ConsolidatedPageID)) ---Seperate the page ID
  851. SELECT @Pageid = CONVERT(INT, CAST('' AS XML).value('xs:hexBinary(substring(sql:variable("@hex_pageid"),sql:column("t.pos")) )',
  852. 'varbinary(max)')) -- Convert Page ID from hex to integer
  853. FROM ( SELECT CASE SUBSTRING(@hex_pageid, , )
  854. WHEN '0x' THEN
  855. ELSE
  856. END
  857. ) AS t ( pos )
  858.  
  859. IF @Context = 'LCX_PFS'
  860. BEGIN
  861. DELETE @temppagedata
  862. INSERT INTO @temppagedata
  863. EXEC
  864. ( 'DBCC PAGE(' + @DataBase_Name + ', '
  865. + @fileid + ', ' + @pageid
  866. + ', 1) with tableresults,no_infomsgs;'
  867. );
  868. INSERT INTO @pagedata
  869. SELECT @ConsolidatedPageID ,
  870. @fileid ,
  871. @pageid ,
  872. @AllocUnitID ,
  873. [ParentObject] ,
  874. [Object] ,
  875. [Field] ,
  876. [Value]
  877. FROM @temppagedata
  878. END
  879. ELSE
  880. IF @Context = 'LCX_TEXT_MIX'
  881. BEGIN
  882. INSERT INTO @ModifiedRawData
  883. SELECT @ConsolidatedPageID ,
  884. @fileid ,
  885. @pageid ,
  886. @Slotid ,
  887. @AllocUnitID ,
  888. NULL ,
  889. ,
  890. CONVERT(INT, CONVERT(VARBINARY, REVERSE(SUBSTRING(@LCX_TEXT_MIX,
  891. , )))) ,
  892. @LCX_TEXT_MIX ,
  893. @LinkID ,
  894.  
  895. END
  896. FETCH NEXT FROM Page_Data_Cursor INTO @ConsolidatedPageID, @Slotid,
  897. @AllocUnitID, @LCX_TEXT_MIX, @LinkID, @Context
  898. END
  899.  
  900. CLOSE Page_Data_Cursor
  901. DEALLOCATE Page_Data_Cursor
  902.  
  903. DECLARE @Newhexstring VARCHAR(MAX);
  904.  
  905. --The data is in multiple rows in the page, so we need to convert it into one row as a single hex value.
  906. --This hex value is in string format
  907. INSERT INTO @ModifiedRawData
  908. ( [PAGE ID] ,
  909. [FILE IDS] ,
  910. [PAGE IDS] ,
  911. [Slot ID] ,
  912. [AllocUnitId] ,
  913. [RowLog Contents 0_var] ,
  914. [RowLog Length]
  915. )
  916. SELECT [Page ID] ,
  917. [FILE IDS] ,
  918. [PAGE IDS] ,
  919. SUBSTRING([ParentObject],
  920. CHARINDEX('Slot', [ParentObject]) + ,
  921. ( CHARINDEX('Offset', [ParentObject])
  922. - ( CHARINDEX('Slot', [ParentObject]) + ) )
  923. - ) AS [Slot ID] ,
  924. [AllocUnitId] ,
  925. SUBSTRING(( SELECT REPLACE(STUFF(( SELECT
  926. REPLACE(SUBSTRING([Value],
  927. CHARINDEX(':',
  928. [Value]) + ,
  929. CHARINDEX('†',
  930. [Value])
  931. - CHARINDEX(':',
  932. [Value])), '†',
  933. '')
  934. FROM @pagedata C
  935. WHERE B.[Page ID] = C.[Page ID]
  936. AND SUBSTRING(B.[ParentObject],
  937. CHARINDEX('Slot',
  938. B.[ParentObject])
  939. + ,
  940. ( CHARINDEX('Offset',
  941. B.[ParentObject])
  942. - ( CHARINDEX('Slot',
  943. B.[ParentObject])
  944. + ) )) = SUBSTRING(C.[ParentObject],
  945. CHARINDEX('Slot',
  946. C.[ParentObject])
  947. + ,
  948. ( CHARINDEX('Offset',
  949. C.[ParentObject])
  950. - ( CHARINDEX('Slot',
  951. C.[ParentObject])
  952. + ) ))
  953. AND [Object] LIKE '%Memory Dump%'
  954. ORDER BY '0x'
  955. + LEFT([Value],
  956. CHARINDEX(':',
  957. [Value]) - )
  958. FOR
  959. XML PATH('')
  960. ), , , ''), ' ', '')
  961. ), , ) AS [Value] ,
  962. SUBSTRING(( SELECT '0x'
  963. + REPLACE(STUFF(( SELECT
  964. REPLACE(SUBSTRING([Value],
  965. CHARINDEX(':',
  966. [Value]) + ,
  967. CHARINDEX('†',
  968. [Value])
  969. - CHARINDEX(':',
  970. [Value])), '†',
  971. '')
  972. FROM
  973. @pagedata C
  974. WHERE
  975. B.[Page ID] = C.[Page ID]
  976. AND SUBSTRING(B.[ParentObject],
  977. CHARINDEX('Slot',
  978. B.[ParentObject])
  979. + ,
  980. ( CHARINDEX('Offset',
  981. B.[ParentObject])
  982. - ( CHARINDEX('Slot',
  983. B.[ParentObject])
  984. + ) )) = SUBSTRING(C.[ParentObject],
  985. CHARINDEX('Slot',
  986. C.[ParentObject])
  987. + ,
  988. ( CHARINDEX('Offset',
  989. C.[ParentObject])
  990. - ( CHARINDEX('Slot',
  991. C.[ParentObject])
  992. + ) ))
  993. AND [Object] LIKE '%Memory Dump%'
  994. ORDER BY '0x'
  995. + LEFT([Value],
  996. CHARINDEX(':',
  997. [Value]) - )
  998. FOR
  999. XML PATH('')
  1000. ), , , ''), ' ', '')
  1001. ), , ) AS [Length]
  1002. FROM @pagedata B
  1003. WHERE [Object] LIKE '%Memory Dump%'
  1004. GROUP BY [Page ID] ,
  1005. [FILE IDS] ,
  1006. [PAGE IDS] ,
  1007. [ParentObject] ,
  1008. [AllocUnitId]--,[Current LSN]
  1009. ORDER BY [Slot ID]
  1010.  
  1011. UPDATE @ModifiedRawData
  1012. SET [RowLog Len] = CONVERT(VARBINARY(), REVERSE(CAST('' AS XML).value('xs:hexBinary(substring(sql:column("[RowLog Length]"),0))',
  1013. 'varbinary(Max)')))
  1014. FROM @ModifiedRawData
  1015. WHERE [LINK ID] =
  1016.  
  1017. UPDATE @ModifiedRawData
  1018. SET [RowLog Contents ] = CAST('' AS XML).value('xs:hexBinary(substring(sql:column("[RowLog Contents 0_var]"),0))',
  1019. 'varbinary(Max)')
  1020. FROM @ModifiedRawData
  1021. WHERE [LINK ID] =
  1022.  
  1023. UPDATE B
  1024. SET B.[RowLog Contents ] = ( CASE WHEN A.[RowLog Contents ] IS NOT NULL
  1025. AND C.[RowLog Contents ] IS NOT NULL
  1026. THEN A.[RowLog Contents ]
  1027. + C.[RowLog Contents ]
  1028. WHEN A.[RowLog Contents ] IS NULL
  1029. AND C.[RowLog Contents ] IS NOT NULL
  1030. THEN C.[RowLog Contents ]
  1031. WHEN A.[RowLog Contents ] IS NOT NULL
  1032. AND C.[RowLog Contents ] IS NULL
  1033. THEN A.[RowLog Contents ]
  1034. END ) ,
  1035. B.[Update] = ISNULL(B.[Update], ) +
  1036. FROM @ModifiedRawData B
  1037. LEFT JOIN @ModifiedRawData A ON A.[Page IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents ],
  1038. + , ))))
  1039. AND A.[File IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents ],
  1040. + , ))))
  1041. AND A.[Link ID] = B.[Link ID]
  1042. LEFT JOIN @ModifiedRawData C ON C.[Page IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents ],
  1043. + , ))))
  1044. AND C.[File IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents ],
  1045. + , ))))
  1046. AND C.[Link ID] = B.[Link ID]
  1047. WHERE ( A.[RowLog Contents ] IS NOT NULL
  1048. OR C.[RowLog Contents ] IS NOT NULL
  1049. )
  1050.  
  1051. UPDATE B
  1052. SET B.[RowLog Contents ] = ( CASE WHEN A.[RowLog Contents ] IS NOT NULL
  1053. AND C.[RowLog Contents ] IS NOT NULL
  1054. THEN A.[RowLog Contents ]
  1055. + C.[RowLog Contents ]
  1056. WHEN A.[RowLog Contents ] IS NULL
  1057. AND C.[RowLog Contents ] IS NOT NULL
  1058. THEN C.[RowLog Contents ]
  1059. WHEN A.[RowLog Contents ] IS NOT NULL
  1060. AND C.[RowLog Contents ] IS NULL
  1061. THEN A.[RowLog Contents ]
  1062. END )
  1063. --,B.[Update]=ISNULL(B.[Update],)+
  1064. FROM @ModifiedRawData B
  1065. LEFT JOIN @ModifiedRawData A ON A.[Page IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents ],
  1066. + , ))))
  1067. AND A.[File IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents ],
  1068. + , ))))
  1069. AND A.[Link ID] <> B.[Link ID]
  1070. AND B.[Update] =
  1071. LEFT JOIN @ModifiedRawData C ON C.[Page IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents ],
  1072. + , ))))
  1073. AND C.[File IDS] = CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING(B.[RowLog Contents ],
  1074. + , ))))
  1075. AND C.[Link ID] <> B.[Link ID]
  1076. AND B.[Update] =
  1077. WHERE ( A.[RowLog Contents ] IS NOT NULL
  1078. OR C.[RowLog Contents ] IS NOT NULL
  1079. )
  1080.  
  1081. UPDATE @ModifiedRawData
  1082. SET [RowLog Contents ] = ( CASE WHEN [RowLog Len] >=
  1083. THEN SUBSTRING([RowLog Contents ],
  1084. , [RowLog Len])
  1085. WHEN [RowLog Len] <
  1086. THEN SUBSTRING([RowLog Contents ],
  1087. + ,
  1088. CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([RowLog Contents ],
  1089. , )))))
  1090. END )
  1091. FROM @ModifiedRawData
  1092. WHERE [LINK ID] =
  1093.  
  1094. UPDATE @ColumnNameAndData
  1095. SET [hex_Value] = [RowLog Contents ]
  1096. --,A.[Update]=A.[Update]+
  1097. FROM @ColumnNameAndData A
  1098. INNER JOIN @ModifiedRawData B ON CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value],
  1099. , )))) = [PAGE IDS]
  1100. AND CONVERT(INT, SUBSTRING([hex_value],
  1101. , )) = B.[Link ID]
  1102. WHERE [System_Type_Id] IN ( , , , , , , , )
  1103. AND [Link ID] <>
  1104.  
  1105. UPDATE @ColumnNameAndData
  1106. SET [hex_Value] = ( CASE WHEN B.[RowLog Contents ] IS NOT NULL
  1107. AND C.[RowLog Contents ] IS NOT NULL
  1108. THEN B.[RowLog Contents ]
  1109. + C.[RowLog Contents ]
  1110. WHEN B.[RowLog Contents ] IS NULL
  1111. AND C.[RowLog Contents ] IS NOT NULL
  1112. THEN C.[RowLog Contents ]
  1113. WHEN B.[RowLog Contents ] IS NOT NULL
  1114. AND C.[RowLog Contents ] IS NULL
  1115. THEN B.[RowLog Contents ]
  1116. END )
  1117. --,A.[Update]=A.[Update]+
  1118. FROM @ColumnNameAndData A
  1119. LEFT JOIN @ModifiedRawData B ON CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value],
  1120. , )))) = B.[PAGE IDS]
  1121. AND B.[Link ID] =
  1122. LEFT JOIN @ModifiedRawData C ON CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value],
  1123. , )))) = C.[PAGE IDS]
  1124. AND C.[Link ID] =
  1125. WHERE [System_Type_Id] IN ( , , , , , , , )
  1126. AND ( B.[RowLog Contents ] IS NOT NULL
  1127. OR C.[RowLog Contents ] IS NOT NULL
  1128. )
  1129.  
  1130. UPDATE @ColumnNameAndData
  1131. SET [hex_Value] = [RowLog Contents ]
  1132. --,A.[Update]=A.[Update]+
  1133. FROM @ColumnNameAndData A
  1134. INNER JOIN @ModifiedRawData B ON CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value],
  1135. , )))) = [PAGE IDS]
  1136. AND CONVERT(INT, SUBSTRING([hex_value],
  1137. , )) = [Link ID]
  1138. WHERE [System_Type_Id] IN ( , , )
  1139. AND [Link ID] <>
  1140.  
  1141. UPDATE @ColumnNameAndData
  1142. SET [hex_Value] = [RowLog Contents ]
  1143. --,A.[Update]=A.[Update]+
  1144. FROM @ColumnNameAndData A
  1145. INNER JOIN @ModifiedRawData B ON CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value],
  1146. , )))) = [PAGE IDS]
  1147. WHERE [System_Type_Id] IN ( , , )
  1148. AND [Link ID] =
  1149.  
  1150. UPDATE @ColumnNameAndData
  1151. SET [hex_Value] = [RowLog Contents ]
  1152. --,A.[Update]=A.[Update]+
  1153. FROM @ColumnNameAndData A
  1154. INNER JOIN @ModifiedRawData B ON CONVERT(INT, CONVERT(VARBINARY(MAX), REVERSE(SUBSTRING([hex_value],
  1155. , )))) = [PAGE IDS]
  1156. WHERE [System_Type_Id] IN ( , , )
  1157. AND [Link ID] =
  1158.  
  1159. UPDATE @ColumnNameAndData
  1160. SET [hex_value] = 0xFFFE + SUBSTRING([hex_value], , LEN([hex_value]))
  1161. --,[Update]=[Update]+
  1162. WHERE [system_type_id] =
  1163.  
  1164. CREATE TABLE [#temp_Data]
  1165. (
  1166. [FieldName] VARCHAR(MAX) ,
  1167. [FieldValue] NVARCHAR(MAX) ,
  1168. [Rowlogcontents] VARBINARY() ,
  1169. [Row ID] INT
  1170. )
  1171.  
  1172. INSERT INTO #temp_Data
  1173. SELECT NAME ,
  1174. CASE WHEN system_type_id IN ( , )
  1175. THEN LTRIM(RTRIM(CONVERT(NVARCHAR(MAX), hex_Value))) --NVARCHAR ,NCHAR
  1176. WHEN system_type_id IN ( , )
  1177. THEN LTRIM(RTRIM(CONVERT(VARCHAR(MAX), hex_Value))) --VARCHAR,CHAR
  1178. WHEN system_type_id IN ( )
  1179. THEN LTRIM(RTRIM(CONVERT(VARCHAR(MAX), hex_Value))) --Text
  1180. WHEN system_type_id IN ( )
  1181. THEN LTRIM(RTRIM(CONVERT(NVARCHAR(MAX), hex_Value))) --nText
  1182. WHEN system_type_id =
  1183. THEN CONVERT(VARCHAR(MAX), CONVERT(TINYINT, CONVERT(BINARY(), REVERSE(hex_Value)))) --TINY INTEGER
  1184. WHEN system_type_id =
  1185. THEN CONVERT(VARCHAR(MAX), CONVERT(SMALLINT, CONVERT(BINARY(), REVERSE(hex_Value)))) --SMALL INTEGER
  1186. WHEN system_type_id =
  1187. THEN CONVERT(VARCHAR(MAX), CONVERT(INT, CONVERT(BINARY(), REVERSE(hex_Value)))) -- INTEGER
  1188. WHEN system_type_id =
  1189. THEN CONVERT(VARCHAR(MAX), CONVERT(BIGINT, CONVERT(BINARY(), REVERSE(hex_Value))))-- BIG INTEGER
  1190. WHEN system_type_id =
  1191. THEN CONVERT(VARCHAR(MAX), CONVERT(DATETIME, CONVERT(VARBINARY(), REVERSE(hex_Value))), ) --DATETIME
  1192. WHEN system_type_id =
  1193. THEN CONVERT(VARCHAR(MAX), CONVERT(SMALLDATETIME, CONVERT(VARBINARY(), REVERSE(hex_Value))), ) --SMALL DATETIME
  1194. WHEN system_type_id =
  1195. THEN CONVERT(VARCHAR(MAX), CONVERT(NUMERIC(, ), CONVERT(VARBINARY, CONVERT(VARBINARY(), xprec)
  1196. + CONVERT(VARBINARY(), xscale))
  1197. + CONVERT(VARBINARY(), ) + hex_Value)) --- NUMERIC
  1198. WHEN system_type_id =
  1199. THEN CONVERT(VARCHAR(MAX), CONVERT(DECIMAL(, ), CONVERT(VARBINARY, CONVERT(VARBINARY(), xprec)
  1200. + CONVERT(VARBINARY(), xscale))
  1201. + CONVERT(VARBINARY(), ) + hex_Value)) --- DECIMAL
  1202. WHEN system_type_id IN ( , )
  1203. THEN CONVERT(VARCHAR(MAX), CONVERT(MONEY, CONVERT(VARBINARY(), REVERSE(hex_Value))), ) --MONEY,SMALLMONEY
  1204. WHEN system_type_id =
  1205. THEN CONVERT(VARCHAR(MAX), CONVERT (BIT, CONVERT(BINARY(), hex_Value)
  1206. % )) -- BIT
  1207. WHEN system_type_id =
  1208. THEN RTRIM(LTRIM(STR(CONVERT(FLOAT, SIGN(CAST(CONVERT(VARBINARY(), REVERSE(hex_Value)) AS BIGINT))
  1209. * ( 1.0
  1210. + ( CAST(CONVERT(VARBINARY(), REVERSE(hex_Value)) AS BIGINT)
  1211. & 0x000FFFFFFFFFFFFF )
  1212. * POWER(CAST( AS FLOAT),
  1213. -) )
  1214. * POWER(CAST( AS FLOAT),
  1215. ( ( CAST(CONVERT(VARBINARY(), REVERSE(hex_Value)) AS BIGINT)
  1216. & 0x7ff0000000000000 )
  1217. / EXP( * LOG())
  1218. - ))), ,
  1219. LEN(hex_Value)))) --- FLOAT
  1220. WHEN system_type_id =
  1221. THEN LEFT(LTRIM(STR(CAST(SIGN(CAST(CONVERT(VARBINARY(), REVERSE(hex_Value)) AS BIGINT))
  1222. * ( 1.0
  1223. + ( CAST(CONVERT(VARBINARY(), REVERSE(hex_Value)) AS BIGINT)
  1224. & 0x007FFFFF )
  1225. * POWER(CAST( AS REAL), -) )
  1226. * POWER(CAST( AS REAL),
  1227. ( ( ( CAST(CONVERT(VARBINARY(), REVERSE(hex_Value)) AS INT) )
  1228. & 0x7f800000 )
  1229. / EXP( * LOG())
  1230. - )) AS REAL), ,
  1231. )), ) --Real
  1232. WHEN system_type_id IN ( , )
  1233. THEN ( CASE WHEN CHARINDEX(0x,
  1234. CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',
  1235. 'VARBINARY(8000)')) =
  1236. THEN '0x'
  1237. ELSE ''
  1238. END ) + CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',
  1239. 'varchar(max)') -- BINARY,VARBINARY
  1240. WHEN system_type_id =
  1241. THEN ( CASE WHEN CHARINDEX(0x,
  1242. CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',
  1243. 'VARBINARY(8000)')) =
  1244. THEN '0x'
  1245. ELSE ''
  1246. END ) + CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',
  1247. 'varchar(max)') --IMAGE
  1248. WHEN system_type_id =
  1249. THEN CONVERT(VARCHAR(MAX), CONVERT(UNIQUEIDENTIFIER, hex_Value)) --UNIQUEIDENTIFIER
  1250. WHEN system_type_id =
  1251. THEN CONVERT(VARCHAR(MAX), CONVERT(SYSNAME, hex_Value)) --SYSNAME
  1252. WHEN system_type_id =
  1253. THEN CONVERT(VARCHAR(MAX), CONVERT(XML, hex_Value)) --XML
  1254. WHEN system_type_id =
  1255. THEN ( CASE WHEN CHARINDEX(0x,
  1256. CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',
  1257. 'VARBINARY(8000)')) =
  1258. THEN '0x'
  1259. ELSE ''
  1260. END ) + CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',
  1261. 'varchar(max)') --TIMESTAMP
  1262. WHEN system_type_id =
  1263. THEN ( CASE WHEN CONVERT(INT, SUBSTRING(hex_Value, ,
  1264. )) =
  1265. THEN CONVERT(VARCHAR(MAX), CONVERT(INT, CONVERT(BINARY(), REVERSE(SUBSTRING(hex_Value,
  1266. ,
  1267. LEN(hex_Value)))))) -- INTEGER
  1268. WHEN CONVERT(INT, SUBSTRING(hex_Value, ,
  1269. )) =
  1270. THEN CONVERT(VARCHAR(MAX), CONVERT(NUMERIC(,
  1271. ), CONVERT(VARBINARY(), SUBSTRING(hex_Value,
  1272. , ))
  1273. + CONVERT(VARBINARY(), SUBSTRING(hex_Value,
  1274. , ))
  1275. + CONVERT(VARBINARY(), )
  1276. + SUBSTRING(hex_Value, ,
  1277. LEN(hex_Value)))) --- NUMERIC
  1278. WHEN CONVERT(INT, SUBSTRING(hex_Value, ,
  1279. )) =
  1280. THEN LTRIM(RTRIM(CONVERT(VARCHAR(MAX), SUBSTRING(hex_Value,
  1281. ,
  1282. LEN(hex_Value))))) --VARCHAR,CHAR
  1283. WHEN CONVERT(INT, SUBSTRING(hex_Value, ,
  1284. )) =
  1285. THEN CONVERT(VARCHAR(MAX), CONVERT(UNIQUEIDENTIFIER, SUBSTRING(( hex_Value ),
  1286. , ))) --UNIQUEIDENTIFIER
  1287. WHEN CONVERT(INT, SUBSTRING(hex_Value, ,
  1288. )) =
  1289. THEN CONVERT(VARCHAR(MAX), CONVERT(DATETIME, CONVERT(VARBINARY(), REVERSE(SUBSTRING(hex_Value,
  1290. ,
  1291. LEN(hex_Value))))), ) --DATETIME
  1292. WHEN CONVERT(INT, SUBSTRING(hex_Value, ,
  1293. )) =
  1294. THEN '0x'
  1295. + SUBSTRING(( CASE WHEN CHARINDEX(0x,
  1296. CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',
  1297. 'VARBINARY(8000)')) =
  1298. THEN '0x'
  1299. ELSE ''
  1300. END )
  1301. + CAST('' AS XML).value('xs:hexBinary(sql:column("hex_Value"))',
  1302. 'varchar(max)'),
  1303. , LEN(hex_Value)) -- BINARY,VARBINARY
  1304. END )
  1305. END AS FieldValue ,
  1306. [Rowlogcontents] ,
  1307. [Row ID]
  1308. FROM @ColumnNameAndData
  1309. ORDER BY nullbit
  1310.  
  1311. --Create the column name in the same order to do pivot table.
  1312.  
  1313. DECLARE @FieldName VARCHAR(MAX)
  1314. SET @FieldName = STUFF(( SELECT ','
  1315. + CAST(QUOTENAME([Name]) AS VARCHAR(MAX))
  1316. FROM syscolumns
  1317. WHERE id = OBJECT_ID(''
  1318. + @SchemaName_n_TableName
  1319. + '')
  1320. FOR
  1321. XML PATH('')
  1322. ), , , '')
  1323.  
  1324. --Finally did pivot table and get the data back in the same format.
  1325.  
  1326. SET @sql = 'SELECT ' + @FieldName
  1327. + ' FROM #temp_Data PIVOT (Min([FieldValue]) FOR FieldName IN ('
  1328. + @FieldName + ')) AS pvt'
  1329. EXEC sp_executesql @sql
  1330.  
  1331. GO

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

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

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

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

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

sqlserver 误删数据恢复的更多相关文章

  1. SqlServer误删数据恢复

    误删数据,操作步骤: 第一步: 找到误删的数据库之前备份文件. 第二步: 1,修改数据库备份模式为:大容量日志 2,修改访问限制为:SINGLE_USER(单用户模式) 第三步: 执行sql一条一条执 ...

  2. 通俗易懂,C#如何安全、高效地玩转任何种类的内存之Span的脾气秉性(二)。 异步委托 微信小程序支付证书及SSL证书使用 SqlServer无备份下误删数据恢复 把list集合的内容写入到Xml中,通过XmlDocument方式写入Xml文件中 通过XDocument方式把List写入Xml文件

    通俗易懂,C#如何安全.高效地玩转任何种类的内存之Span的脾气秉性(二).   前言 读完上篇<通俗易懂,C#如何安全.高效地玩转任何种类的内存之Span的本质(一).>,相信大家对sp ...

  3. SQLSERVER误删除了Windows登录用户验证方式使用Windows身份验证的解决方法

    SQLSERVER误删Windows登录用户验证方式使用Windows身份验证的解决方法 今天看到这篇文章:没有了SA密码,无法Windows集成身份登录,DBA怎么办? 想起来之前着急哥问我的一个问 ...

  4. SQLSERVER误删Windows登录用户

    SQLSERVER误删除了Windows登录用户验证方式使用Windows身份验证的解决方法   SQLSERVER误删Windows登录用户验证方式使用Windows身份验证的解决方法 今天看到这篇 ...

  5. sql server误删数据恢复delete(低效版)

    关键词:sql server误删数据恢复,mssql误删数据恢复,delete --切换数据库 use master --构建函数 Create PROCEDURE Recover_Deleted_D ...

  6. SqlServer无备份下误删数据恢复

    系统已上线,给客户修改bug的时候,使用delete语句删表数据,没想到库没切换成测试库.误删了正式库的数据,而且一次备份都没有做过,玩大了 不扯了,进入主题 网上很多方法,都是针对至少有一次备份的情 ...

  7. SQLSERVER2012误删数据恢复过程

    由于长时间从事企业应用系统开发,前往用户现场升级.调试系统是比较常做的事情,但是就在周一,由于同事的失误在毫无知觉的情况下误删了生产数据库几乎所有的数据.当我发现的那一刻,感觉头发都立起来了,心想这他 ...

  8. sqlserver 误删数据库恢复

    本文为转载 原文:https://blog.csdn.net/xwnxwn/article/details/53537841 由于长时间从事企业应用系统开发,前往用户现场升级.调试系统是比较常做的事情 ...

  9. oracle 误删数据恢复

    1.根据时间点查系统版本号scn: select timestamp_to_scn(to_timestamp('2013-01-07 11:20:00','YYYY-MM-DD HH:MI:SS')) ...

随机推荐

  1. [BZOJ 3680] 吊打XXX 【模拟退火】

    题目链接:BZOJ - 3680 题目分析 这道题是SLYZ的神犇把JSOI的平衡点那道题改了一下题面变成了吊打GTY神犇..Orz 第一次写模拟退火,只能照着别人的代码写,我看的是PoPoQQQ神犇 ...

  2. GCD介绍(一): 基本概念和Dispatch Queue

    什么是GCD? Grand Central Dispatch或者GCD,是一套低层API,提供了一种新的方法来进行并发程序编写.从基本功能上讲,GCD有点像NSOperationQueue,他们都允许 ...

  3. 【转载】利用jetty+Eclipse实现超轻量级web开发

    之前一直使用maven的jetty插件.今天换种方式. 使用下面介绍的方式你只有一个java project就行. 开发环境更简单,debug也更方便,不需要remote debug的方式,jetty ...

  4. Unity3D 命令行参数

    Unity3D 命令行参数 @by 广州小龙                                              unity ios开发群:63438968 Typically, ...

  5. SQL表建立,临时表,表变量示例

    CODE: USE Sales; GO /* CREATE TABLE Orders ( OrderID int IDENTITY(1,1) PRIMARY KEY, OrderGUI uniquei ...

  6. Android 判断是否联网 是否打开上网

    ConnectivityManager cwjManager=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); ...

  7. ExecutorService介绍

    转自: http://victorzhzh.iteye.com/blog/1010359 下面是excutor相关的类结果: ExecutorService接口继承了Executor接口,定义了一些生 ...

  8. C语言头文件的使用与写法

    C语言中的.h文件和我认识由来已久,其使用方法虽不十分复杂,但我却是经过了几个月的“不懂”时期,几年的“一知半解”时期才逐渐认识清楚他的本来面目.揪其原因,我的驽钝和好学而不求甚解固然是原因之一,但另 ...

  9. struts2表单验证

    1:采用手工编写代码实现. 通过继承ActionSupport类,然后重写vlidate方法,validate方法会校验跟execute同样签名的方法,当某个数据校验失败时,我们应该调用addFiel ...

  10. 查看SGA和PGA使用率

    select name,total,round(total-free,2) used, round(free,2) free,round((total-free)/total*100,2) pctus ...