Sql获取sql server中特定数据库的最新完整备份文件
我需要一个 sql 命令(dbcc 或扩展存储过程?)或可以从 sql server 存储过程调用的命令来获取特定数据库可用的最新完整备份文件。备份文件的名称将放置在 varchar 变量中,我可以将其与存储过程中的 RESTORE DATABASE 命令一起使用。此过程将用于从生产数据库恢复到沙箱/训练数据库,因此恢复完成后,我需要该过程继续运行,以便我可以对数据库进行一些修改。
I need an sql command (dbcc or extended stored procedure?) or something that can be called from a sql server stored procedure to get the most recent full backup file available for a specific database. The name of the backup file will be placed in a varchar variable that I can use with a RESTORE DATABASE command in the stored procedure. This procedure will be used to restore from production database to a sandbox/training database, so after the restore completes I need the procedure to continue running so I can make a few modifications to the db.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
只是想对 user2378139 的优秀答案进行补充。我经常需要从1个文件夹中恢复多个数据库,并且该文件夹中的每个数据库都会有多个备份副本。我需要获取最新的,并在计划任务上运行它。以下是我为实现这一目标所做的编辑/更新。临时表比我想要的要多,但还没有找到更好的方法:
Just wanted to give an addition to the excellent answer from user2378139. I often have the need to restore multiple databases from 1 folder, and there will be multiple backup copies for each database in that folder. I need to get the most recent, and run that on a scheduled task. Below is my edit/update to make that happen. There are more temporary tables than i'd like, but haven't figured a better way to do it yet:
这是建立在上述答案的基础上的。
源数据库和恢复数据库位于脚本中的多个位置。
这就为错误留下了空间,即您无法在需要的位置之一更正数据库名称或恢复数据库名称。
下面使用@user5054734的解决方案获取备份文件。
剩下的就是生成 SQL,然后执行 exec('sql string')
作为模板,我使用了通过恢复向导为我生成的 MSSQL 脚本。
我还将引用 @user2378139 的 exec(@sql) 方法。我已经有一段时间没有这样做了。
您必须使用 exec(''),因为 RESTORE DATABASE 命令无法使用命令中嵌入的变量。 (如果可以,请告诉我如何......很确定它不能)。
我希望生成的 sql 示例如下所示 这
是生成该 SQL 然后执行它的脚本
希望它对某人有所帮助。
将 @backupfile 声明为 Varchar(255)
,@dataFolder varchar(255) = N'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA'
, @sourceDatabaseName varchar(100) = 'circupool'
, @restoreDatabaseName varchar(100) ='circupool_testDWH'
选择 TOP 1 @backupfile=mf.physical_device_name from msdb..backupset bk
在 bk.media_set_id = mf.media_set_id
上加入 msdb..backupmediafamily mf
其中database_name=N'circupool' 和bk.type='D' order by
backup_set_id desc
声明 @restoreMDF varchar(200) = concat(@dataFolder,@restoreDatabaseName,'.mdf')
, @sourceLogFile varchar(200) = concat(@sourceDatabaseName,'_Log')
, @restoreLog varchar(200) = concat(@dataFolder,@restoreDatabaseName, '_log.ldf')
选择
@备份文件 [备份文件]
,@dataFolder [dataFolder]
, @sourceLogFile [sourceLogFile]
, @restoreDatabaseName [restoreDBname]
,@restoreMDF [恢复MDF]
, @restoreLog [restorelog]
声明 @crlf varchar(10) = CHAR(13) + CHAR(10)
声明 @sql varchar(1000) =
concat('ALTER DATABASE [',@restoreDatabaseName, '] 设置单用户立即回滚;', @crlf
,'从磁盘恢复数据库 [',@restoreDatabaseName,'] = ''',@backupfile,'''WITH FILE = 1 ',@crlf
,',移动 ''',@sourceDatabaseName, ''' 到 ''',@restoreMDF,'''', @crlf
,',移动''',@sourceLogFile,'''到''',@restoreLog,'''',@crlf
,', NOUNLOAD, 替换, 统计 = 5', @crlf
,'更改数据库 [circupool_testDWH] 设置多用户',@crlf
)
打印@sql
exec( @sql ) 和 bk.type='D' 排序依据
backup_set_id 描述
This builds on the above answers.
The Source and Restore Databases are in the script in several places.
That leaves room for a mistake where you fail to correct the database name or restoreDatabase name in one of the places it needs to be.
the following gets the backup file using @user5054734's solution.
the rest is generating SQL and then doing and exec('sql string')
As a template , I used the script MSSQL generated for me using the restore wizard.
Ill also cite @user2378139 for the exec(@sql) approach. I had not done that in a while.
You have to use exec('') because the RESTORE DATABASE command can not use variables embedded in the command. (If it can, please show me how.. pretty sure it can not).
An example of the sql I wish to generate looks like this
Here is the script that produces that SQL and then executes it
Hope it helps someone.
declare @backupfile as Varchar(255)
, @dataFolder varchar(255) = N'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA'
, @sourceDatabaseName varchar(100) = 'circupool'
, @restoreDatabaseName varchar(100) ='circupool_testDWH'
SELECT TOP 1 @backupfile=mf.physical_device_name from msdb..backupset bk
join msdb..backupmediafamily mf on bk.media_set_id = mf.media_set_id
where database_name=N'circupool' and bk.type='D' order by
backup_set_id desc
declare @restoreMDF varchar(200) = concat(@dataFolder,@restoreDatabaseName,'.mdf')
, @sourceLogFile varchar(200) = concat(@sourceDatabaseName,'_Log')
, @restoreLog varchar(200) = concat(@dataFolder,@restoreDatabaseName, '_log.ldf')
select
@backupfile [backupfile]
, @dataFolder [dataFolder]
, @sourceLogFile [sourceLogFile]
, @restoreDatabaseName [restoreDBname]
, @restoreMDF [restoreMDF]
, @restoreLog [restorelog]
declare @crlf varchar(10) = CHAR(13) + CHAR(10)
declare @sql varchar(1000) =
concat('ALTER DATABASE [',@restoreDatabaseName, '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;', @crlf
,'RESTORE DATABASE [',@restoreDatabaseName, '] FROM DISK = ''',@backupfile,''' WITH FILE = 1 ', @crlf
,',MOVE ''',@sourceDatabaseName, ''' TO ''',@restoreMDF,'''', @crlf
,',MOVE ''',@sourceLogFile,''' TO ''', @restoreLog, '''', @crlf
,', NOUNLOAD, REPLACE, STATS = 5', @crlf
,'ALTER DATABASE [circupool_testDWH] SET MULTI_USER', @crlf
)
print @sql
exec( @sql ) and bk.type='D' order by
backup_set_id desc
只需在“源”产品上查询 msdb..backupset (MSDN)服务器
和工作示例 (SQL Rockstar) 太
编辑,2018
Just query msdb..backupset (MSDN) on the "source" prod server
And a working example (SQL Rockstar) too
Edit, 2018
我有一个方便的脚本,当我将最近的备份从目录还原到要还原到的数据库时,我会使用该脚本。它非常适合通过夜间工作来刷新开发或测试箱!
I have a handy script that I use when I restore the most recent backup from a directory to the database you want to restore to. It is great for refreshing a dev or test box by using a nightly job!