SQL Server 误操作解决方案
问题:
经常看到有人误删数据,或者误操作,特别是 UPDATE和 DELETE 的时候没有加 WHERE,然后就扎心了。
人非圣贤孰能无过,做错可以理解,但不能纵容,这个以后再说,现在先来解决问题。
遇到这种情况,一般都是没有做备份,不然也不会来发问了。首先要 冷静!!!,否则会有更大的灾难。直到你放弃。话不多说,请看下文。
/*****************
步骤:
1、将数据库属性》选项》恢复模式,设置为完整。可使用下面语句查询当前恢复模式
SELECT recovery_model,recovery_model_desc
FROM sys.databases
WHERE name =’DataBaseRecover’
确保数据库的恢复模式位“完整”模式
2、做1次“完整”备份。使用以下语句可查询备份信息
SELECT database_name,recovery_model,name,backup_finish_date
FROM msdb.dbo.backupset
3、插入一些数据。 4、删除数据。 USE DataBaseRecover GO WAITFOR TIME '10:29' DELETE FROM dbo.STUDENT SELECT * FROM dbo.STUDENT 为了定位是啥时候发生的,加了一个waitfor命令,让它在某个时间发生,这样恢复的时候就有准确性。 5、再做1“完整”备份。 6、断开数据库所有连接 7、做一次 “日志尾部备份” !!!!!! (1)使用可视化工具备份 右击数据库》任务》备份》 常规:【备份类型:事务日志】 选项:【可靠性:√ 完成后验证备份;√ 写入介质前检查校验】 【事务日志:√ 备份日志尾部】 点击确定。 (2)使用语句备份 USE Master GO BACKUP LOG [DataBaseRecover] TO DISK = N'F:\DataBaseRecover_TransLog_Backup.bak' WITH NO_TRUNCATE , NOFORMAT, NOINIT, NAME = N'DataBaseRecover-事务日志 备份', SKIP, NOREWIND, NOUNLOAD, NORECOVERY , COMPRESSION, STATS = 10, CHECKSUM GO declare @backupSetId as int select @backupSetId = position from msdb..backupset where database_name=N'DataBaseRecover' and backup_set_id=(select max(backup_set_id) from msdb..backupset where database_name=N'DataBaseRecover' ) if @backupSetId is null begin raiserror(N'验证失败。找不到数据库“AdventureWorks”的备份信息。', 16, 1) end RESTORE VERIFYONLY FROM DISK = N'E:\DataBaseRecover_TransLog_Backup.bak' WITH FILE = @backupSetId, NOUNLOAD, NOREWIND GO 如果备份不了,使用以下语句查看,并把spid杀掉 SELECT * FROM sys.sysprocesses WHERE dbid=DB_ID('DataBaseRecover') 然后kill掉。接着继续备份。 8、此时,数据库处于“正在还原“状态 9、开始还原 (1)还原文件和文件组(数据库): 常规》选择最近的一次“完整”备份 选项》恢复状态:选择“不对数据库执行任何操作” (2)还原“事务日志” 常规》时间点:把时间点指定到你误删除的时间之前 (这里我的删除操作是10:29:00,我这里还原时选择的是10:28:00) 选项》恢复状态:选择“回滚未提交的事务” 10、完成。检查数据是否恢复
总结:
平时尽量做备份,别等到出问题来喊急,数据无价,操作需谨慎,那以后出问题就别怪微软了。
本文中的方法看上去有点繁琐,但是实操几次就觉得好了,但是步骤建议严格按照上面说的,因为一旦操作错误,就很麻烦,此时再次强调——冷静冷静再冷静!!!!!!
这种方法有几个缺点:
1、 如果你发现误操作以后还有很多人做了操作,那么你还原成功后,别人的操作就会冲掉,所以发生误操作后,要马上停止别人对数据库的操作。
2、 这个方法要对数据库独占,所以你想偷偷恢复是不行的了。勇敢承认错误吧。
对于核心数据表,还是要先做好预防操作,可以看:SQLServer恢复表级数据。
******************/
本文作者测试用例:
/*************************** 准备: 创建测试数据库,数据表,插入默认数据 ****************************/ /*******************创建数据库****************************/ IF db_id('DataBaseRecover') IS NOT NULL PRINT db_id('DataBaseRecover') DROP DATABASE DataBaseRecover GO CREATE DATABASE DataBaseRecover GO USE DataBaseRecover GO /********************创建学生表***************************/ CREATE TABLE STUDENT( StuId INT IDENTITY(1,1) PRIMARY KEY NOT NULL, StuName NVARCHAR(16) NOT NULL ) EXEC sys.sp_addextendedproperty @name = N'MS_Description', -- sysname @value = N'学号', -- sql_variant @level0type = N'USER', -- varchar(128) @level0name = N'DBO', -- sysname @level1type = N'TABLE', -- varchar(128) @level1name = N'STUDENT', -- sysname @level2type = N'COLUMN', -- varchar(128) @level2name = N'StuId' -- sysname EXEC sys.sp_addextendedproperty @name = N'MS_Description', -- sysname @value = N'学生姓名', -- sql_variant @level0type = N'USER', -- varchar(128) @level0name = N'DBO', -- sysname @level1type = N'TABLE', -- varchar(128) @level1name = N'STUDENT', -- sysname @level2type = N'COLUMN', -- varchar(128) @level2name = N'StuName' -- sysname /********************插入默认数据****************************/ INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户001' ) INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户002' ) INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户003' ) INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户004' ) INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户005' ) INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户006' ) INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户007' ) INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户008' ) INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户009' ) INSERT INTO DBO.STUDENT( StuName )VALUES ( N'用户010' ) /*********************创建得分表*******************************/ IF OBJECT_ID('SCORES','U') IS NOT NULL DROP TABLE SCORES GO CREATE TABLE SCORES ( SCOREID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY , STUID INT NOT NULL , SCORE DECIMAL NULL ); GO /********************插入默认数据****************************/ INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( 1, 60 ) INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( 2, 70 ) INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( 3, 80 ) INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( 4, 90 ) INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( 5, 100 ) INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( 6, 65 ) INSERT INTO dbo.SCORES( STUID, SCORE )VALUES ( 7, 78 ) /**查询:学生表*/ SELECT STUID,StuName FROM dbo.STUDENT /**查询:得分表*/ SELECT SCOREID,STUID,SCORE FROM dbo.SCORES