从SQL Server 2008备份恢复到2016时如何重命名表并正确恢复?
解决SQL Server备份恢复中表名差异的问题
你遇到的这个表名差异(旧库Stdnents vs 新库Students)确实会让直接恢复整个数据库变得棘手——毕竟直接覆盖现有库会丢失新库的Students表数据,这显然不是你想要的。下面给你几个靠谱的解决方案,结合你已有的代码来调整:
方案1:先恢复到临时数据库,再迁移目标表数据
这是最稳妥的方式,既不会影响现有新库,又能完整获取旧库的Stdnents数据:
步骤1:修改你的恢复代码,恢复到临时库
先把备份恢复到一个临时数据库(比如TempOldDB),避免干扰现有NewSqlDatabase:
-- 先获取数据库文件路径(复用你已有的代码) RESTORE FILELISTONLY FROM DISK='f:\newBDbackup.bak' declare @DefaultData nvarchar(512) exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'DefaultData', @DefaultData output declare @DefaultLog nvarchar(512) exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'DefaultLog', @DefaultLog output declare @MasterData nvarchar(512) exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer\Parameters', N'SqlArg0', @MasterData output select @MasterData=substring(@MasterData, 3, 255) select @MasterData=substring(@MasterData, 1, len(@MasterData) - charindex('\', reverse(@MasterData))) declare @MasterLog nvarchar(512) exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer\Parameters', N'SqlArg2', @MasterLog output select @MasterLog=substring(@MasterLog, 3, 255) select @MasterLog=substring(@MasterLog, 1, len(@MasterLog) - charindex('\', reverse(@MasterLog))) -- 赋值临时库的文件路径 declare @TempDataPath nvarchar(512) = ISNULL(@DefaultData, @MasterData) + '\TempOldDB.mdf' declare @TempLogPath nvarchar(512) = ISNULL(@DefaultLog, @MasterLog) + '\TempOldDB_log.ldf' -- 恢复到临时库 RESTORE DATABASE TempOldDB FROM DISK='f:\newBDbackup.bak' WITH MOVE 'newDatabase' TO @TempDataPath, MOVE 'newDatabase_log' TO @TempLogPath, REPLACE, -- 若临时库已存在则替换 STATS=10; -- 显示恢复进度
步骤2:将临时库的Stdnents数据导入新库的Students表
因为两张表结构完全相同,直接用INSERT...SELECT就能完成数据迁移:
USE NewSqlDatabase; -- 如果需要清空新库的Students表再导入,加这行(可选) -- TRUNCATE TABLE Students; -- 导入数据 INSERT INTO Students SELECT * FROM TempOldDB.dbo.Stdnents;
步骤3:清理临时库
数据迁移完成后,可以删除临时库释放空间:
DROP DATABASE TempOldDB;
方案2:仅从备份中提取Stdnents表(跳过整库恢复)
如果你只需要Stdnents这一张表的数据,可以用OPENROWSET直接从备份文件读取数据,无需恢复整个库:
USE NewSqlDatabase; INSERT INTO Students SELECT * FROM OPENROWSET( BULK 'f:\newBDbackup.bak', FORMATFILE = 'C:\Path\To\Your\FormatFile.fmt' -- 需要先生成格式文件 ) AS BackupData;
不过这个方法需要先为Stdnents表生成格式文件,操作相对繁琐,所以更推荐方案1。
关键提醒
- 不要直接用
REPLACE参数恢复到现有NewSqlDatabase,这会完全覆盖新库的所有数据,包括你需要保留的Students表。 - 迁移数据前最好先备份新库的
Students表,避免意外数据丢失:SELECT * INTO Students_Bak FROM Students;
内容的提问来源于stack exchange,提问作者slickchick2




