首页/数据/备份与容灾速查/SQL Server 单表恢复

SQL Server 单表恢复

误删表或误改数据时:把完整备份以新库名还原到同一实例,再用 T-SQL 把目标表数据导回,全过程不覆盖生产库。

备份与容灾速查数据更新于 2026-10-13

SQL Server 单表恢复是什么

SQL Server 没有「只还原一张表」的命令:误删表或误改数据时,常规做法是把完整备份以新库名还原到同一实例(用 MOVE 指定新的数据与日志文件位置),再从临时库把目标表的数据导回生产库。整个过程不覆盖生产库,生产侧只承受导回动作带来的影响。

基本信息

适用平台SQL Server(RESTORE ... WITH MOVE 语法通用)
前提条件有可用的完整备份,且实例磁盘空间足够放一份副本
关键参数MOVE 指定数据与日志文件的新位置
常用选项RECOVERY 与 NORECOVERY、STOPAT 时间点还原
回导方式INSERT ... SELECT 或 MERGE,配合 NOT EXISTS 保证幂等
收尾动作验证完成后删除临时库,避免占用空间与合规风险

典型使用场景

  • 误删表或误删部分行后精确找回数据
  • 误更新覆盖了正确数据,需要回到操作前的行版本
  • 有审计要求,需要保留完整的恢复过程记录
  • 需要在指定时间点还原时,用日志备份配合 STOPAT
  • 演练:在完全不影响生产的前提下验证备份可恢复性

还原到新库并导回数据

还原到新库并导回数据
# 1) 把完整备份还原成新库(库名与文件名都要改)
RESTORE DATABASE [AppDB_rescue] FROM DISK = N'D:\backup\AppDB-full.bak' WITH MOVE N'AppDB' TO N'D:\data\AppDB_rescue.mdf', MOVE N'AppDB_log' TO N'D:\data\AppDB_rescue_log.ldf', RECOVERY, STATS = 10;
# 2) 只导回缺失的行(幂等写法)
INSERT INTO [AppDB].[dbo].[Orders] (Id, OrderNo, CreatedAt) SELECT s.Id, s.OrderNo, s.CreatedAt FROM [AppDB_rescue].[dbo].[Orders] AS s WHERE NOT EXISTS (SELECT 1 FROM [AppDB].[dbo].[Orders] AS t WHERE t.Id = s.Id);
# 3) 核对行数与关键业务口径
SELECT COUNT(*) FROM [AppDB].[dbo].[Orders];
# 4) 确认无误后清理临时库
DROP DATABASE [AppDB_rescue];

还原与导回要点读法

要点作用注意
MOVE把数据与日志文件放到新路径漏写会尝试使用生产库文件路径,直接失败或造成更大事故
RECOVERY / NORECOVERY还原后数据库是否可用还要继续还原日志备份时必须用 NORECOVERY
STOPAT还原到指定时间点依赖完整的日志备份链,缺链会直接报错
幂等导回用 NOT EXISTS 或 MERGE 避免重复插入简单 INSERT ... SELECT 会把重复行写进去
临时库清理验证后删除临时库长期留着占空间,也扩大数据可访问面
导回前先核对表结构与索引:临时库与生产库版本不一致时,导回语句要显式列出列名,避免依赖列顺序。
还原过程只读不写生产库,风险集中在导回那一步:先在临时库上把导回语句跑通并核对行数,再对生产执行。

易错点

  • 还原时未用 MOVE,直接覆盖生产库文件:恢复动作本身变成更大的事故
  • 导回语句写 SELECT * 且列顺序与生产表不一致:列错位写入脏数据
  • 导回条件没写 WHERE 或去重:同一批数据被重复插入,业务数据被污染
  • 临时库长期不删:占用空间、扩大数据访问面,还容易被人误当作正式库使用

数据来源与参考

  • Microsoft Learn(RESTORE WITH MOVE / 表级数据恢复思路)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌