我最近偶然發現了一篇博客文章,其中討論了一個名為的存盤程序Recover_Deleted_Data_Proc.sql,該程序顯然可以從.log檔案中恢復您洗掉的資料。
太陽底下沒有新鮮事,我們要用fn_dblog.
重現步驟
我們首先要創建表:
--Create Table
CREATE TABLE [Test_Table]
(
[Col_image] image,
[Col_text] text,
[Col_uniqueidentifier] uniqueidentifier,
[Col_tinyint] tinyint,
[Col_smallint] smallint,
[Col_int] int,
[Col_smalldatetime] smalldatetime,
[Col_real] real,
[Col_money] money,
[Col_datetime] datetime,
[Col_float] float,
[Col_Int_sql_variant] sql_variant,
[Col_numeric_sql_variant] sql_variant,
[Col_varchar_sql_variant] sql_variant,
[Col_uniqueidentifier_sql_variant] sql_variant,
[Col_Date_sql_variant] sql_variant,
[Col_varbinary_sql_variant] sql_variant,
[Col_ntext] ntext,
[Col_bit] bit,
[Col_decimal] decimal(18,4),
[Col_numeric] numeric(18,4),
[Col_smallmoney] smallmoney,
[Col_bigint] bigint,
[Col_varbinary] varbinary(Max),
[Col_varchar] varchar(Max),
[Col_binary] binary(8),
[Col_char] char,
[Col_timestamp] timestamp,
[Col_nvarchar] nvarchar(Max),
[Col_nchar] nchar,
[Col_xml] xml,
[Col_sysname] sysname
)
然后我們向其中插入資料:
--Insert data into it
INSERT INTO [Test_Table]
([Col_image]
,[Col_text]
,[Col_uniqueidentifier]
,[Col_tinyint]
,[Col_smallint]
,[Col_int]
,[Col_smalldatetime]
,[Col_real]
,[Col_money]
,[Col_datetime]
,[Col_float]
,[Col_Int_sql_variant]
,[Col_numeric_sql_variant]
,[Col_varchar_sql_variant]
,[Col_uniqueidentifier_sql_variant]
,[Col_Date_sql_variant]
,[Col_varbinary_sql_variant]
,[Col_ntext]
,[Col_bit]
,[Col_decimal]
,[Col_numeric]
,[Col_smallmoney]
,[Col_bigint]
,[Col_varbinary]
,[Col_varchar]
,[Col_binary]
,[Col_char]
,[Col_nvarchar]
,[Col_nchar]
,[Col_xml]
,[Col_sysname])
VALUES
(CONVERT(IMAGE,REPLICATE('A',4000))
,REPLICATE('B',8000)
,NEWID()
,10
,20
,3000
,GETDATE()
,4000
,5000
,getdate() 15
,66666.6666
,777777
,88888.8888
,REPLICATE('C',8000)
,newid()
,getdate() 30
,CONVERT(VARBINARY(8000),REPLICATE('D',8000))
,REPLICATE('E',4000)
,1
,99999.9999
,10101.1111
,1100
,123456
,CONVERT(VARBINARY(MAX),REPLICATE('F',8000))
,REPLICATE('G',8000)
,0x4646464
,'H'
,REPLICATE('I',4000)
,'J'
,CONVERT(XML,REPLICATE('K',4000))
,REPLICATE('L',100)
)
GO
我們現在要驗證資料是否存在:
--Verify the data
SELECT * FROM Test_Table
此時我們需要創建存盤程序。我無法將其粘貼到此處,因為它太長了,但您可以從同一篇博客文章中下載它,其中有一個指向Box 檔案的鏈接。
如果查詢給你帶來這樣的麻煩:
Msg 50000, Level 16, State 1, Procedure Recover_Deleted_Data_Proc, Line 22 [Batch Start Line 700] The compatibility level should be equal to or greater SQL SERVER 2005 (90)
Msg 50000, Level 16, State 1, Procedure Recover_Deleted_Data_Proc, Line 22 [Batch Start Line 705] The compatibility level should be equal to or greater SQL SERVER 2005 (90)
是因為你從行注釋掉701到線708。
很酷,現在讓我們從該表中洗掉資料:
--Delete the data
DELETE FROM Test_Table
And confirm that the data were deleted:
--Verify the data
SELECT * FROM Test_Table
And here is the last step: we need to try to recover the data using the freshly installed stored procedure.
The author instruct us to use one of these two commands (don't forget to change 'test' with the name of your database):
--Recover the deleted data without date range
EXEC Recover_Deleted_Data_Proc 'test', 'dbo.Test_Table'
or
--Recover the deleted data it with date range
EXEC Recover_Deleted_Data_Proc 'test', 'dbo.Test_Table', '2012-06-01', '2012-06-30'
But the problem is that both returns this error:
(8 rows affected)
(2 rows affected)
(64 rows affected)
(2 rows affected)
(1 row affected)
(1 row affected)
(1 row affected)
(1 row affected)
(1 row affected)
(1 row affected)
Msg 245, Level 16, State 1, Procedure Recover_Deleted_Data_Proc, Line 485 [Batch Start Line 112]
Conversion failed when converting the varchar value '0x41-->01 ; 0001' to data type int.
If I right click on the stored procedure and I click "Modify", I don't see anything particularly fishy at Line 485.
Any idea why this stored procedure is not working?
What is the conversion mentioned?
uj5u.com熱心網友回復:
該代碼已有10 年歷史,并且假設 a[PAGE ID]永遠只能表示為一對整數,例如0001:00000138- 但是,正如您所了解的,有時表達方式不同,例如0x41-->01 ; 0001:00000138.
您可以通過在游標中添加以下內容來解決該問題:
IF @ConsolidatedPageID LIKE '0x%-->%;%'
BEGIN
SET @ConsolidatedPageID = LTRIM(SUBSTRING(@ConsolidatedPageID,
CHARINDEX(';', @ConsolidatedPageID) 1, 8000));
END
但是你的下一個問題是當你從 box 檔案中保存程式時,它可能會變成'?'一些古怪的?角色。當我修復它時(N'?'當然使用,因為 Unicode 字符應該總是有N),我仍然收到這些錯誤訊息:
訊息 537,級別 16,狀態 3,程序 Recover_Deleted_Data_Proc,第 525 行
傳遞給 LEFT 或 SUBSTRING 函式的長度引數無效。
訊息 9420,級別 16,狀態 1,程序 Recover_Deleted_Data_Proc,第 651 行
XML 決議:第 1 行,字符 2,非法 xml 字符
在嘗試對這個意大利面條進行逆向工程 15 分鐘后,我放棄了。如果您需要恢復已洗掉的資料,請恢復備份。如果您沒有備份,那么,這就是我們進行備份的原因。人們試圖創建以彌補不備份的脆弱腳本正是日志恢復供應商收取大筆費用的原因。
順便說一句,兼容性級別的錯誤訊息是一個紅鯡魚,完全誤導了當前撰寫的邏輯,并且與問題完全無關。但它可以解決,如果,就在此之前:
IF ISNULL(@Compatibility_Level,0)<=80
BEGIN
RAISERROR('The compatibility level should ... blah blah',16,1)
RETURN
END
你添加這個:
IF DB_ID(@Database_Name) IS NULL
BEGIN
RAISERROR(N'Database %s does not exist.',11,1,@Database_name);
RETURN;
END
或者只是不在腳本末尾呼叫這兩個示例呼叫,因為它們取決于您擁有一個名為 的資料庫test,而您顯然沒有。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/358336.html
標籤:sql-server tsql stored-procedures scripting data-conversion
