home
s_RestoreDatabase - restore full backup and apply logs
Author Nigel Rivett
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[s_RestoreDatabase]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[s_RestoreDatabase]
GO
create proc s_RestoreDatabase
@SourcePath varchar(200) ,
@archivePath varchar(200) ,
@DataPath varchar(200) ,
@LogPath varchar(200) ,
@recover varchar(10) , -- recover, norecovery, standby
@recipients varchar(128) = null ,
@Database varchar(128) = null , -- only restore this database
@Debug int = 0
as
/*
exec s_RestoreDatabase
@SourcePath = 'c:\atest\' ,
@archivePath = 'c:\atest\archive\' ,
@DataPath = 'c:\atest\' ,
@LogPath = 'c:\atest\' ,
@recover = 'norecovery' ,
@recipients = ''
*/
/*
Get all files from directory (they will be *.bak)
The process is controlled by the files in the directory
If there is a full backup then restore it.
If there is a diff then restore it next.
Restore any logs
Recover database if necessary
*/
declare @dbname varchar(128) ,
@cmd varchar(2000) ,
@filename varchar(128) ,
@s varchar(128) ,
@t varchar(128) ,
@sql nvarchar(2000)
create table #files (lname varchar(128), pname VARCHAR(128), type varchar(10), fgroup varchar(128), size varchar(50), maxsize varchar(50))
create table #dir (s varchar(2000))
-- get list of files in directory
select @cmd = 'dir /B ' + @SourcePath + '*.bak'
insert #dir exec master..xp_cmdshell @cmd
delete #dir
where s is null
or s not like '%.bak'
or ( s not like '%^_Full^_%' escape '^'
and s not like '%^_Log^_%' escape '^'
)
if @Database is not null
delete #dir
where s not like @Database + '^_%' escape '^'
if @Debug = 1
select * from #dir
-- deal with each database in turn
while exists (select * from #dir)
begin
-- any with a full first
select @dbname = null
select top 1 @dbname = left(s,charindex('_Full_', s) - 1)
from #dir
where charindex('_Full_', s) <> 0
order by s
-- no full - get log
if @dbname is null
begin
select @dbname = null
select top 1 @dbname = left(s,charindex('_Log_', s) - 1)
from #dir
where charindex('_Log_', s) <> 0
order by s
end
-- find the last full backup for this db
select @filename = null
select @filename = max(s)
from #dir
where s like @dbname + '_Full_%.bak'
-- archive everything for this db that appears before this file
select @s = ''
while @s is not null and @filename is not null
begin
select top 1 @s = s
from #dir
where s like @dbname + '%'
order by right(s, 20)
if @s = @filename
begin
select @s = null
end
else
begin
-- move to archive
select @cmd = 'move ' + @SourcePath + @s + ' ' + @archivePath + @s
exec master..xp_cmdshell @cmd
delete #dir where s = @s
end
end
-- now we can go through each file in turn for this database and restore it
while exists (select * from #dir where s like @dbname + '^_%' escape '^')
begin
select top 1 @filename = s
from #dir
where s like @dbname + '^_%' escape '^'
order by right(s, 20)
if @Debug <> 0
select filename = @filename
if @filename like '%^_Full^_%' escape '^'
begin
-- restore a full backup
if exists (select * from master..sysdatabases where name = @dbname)
begin
select @cmd = 'drop database ' + @dbname
exec (@cmd)
end
select @cmd = 'restore filelistonly from disk = ''' + @SourcePath + @filename + ''''
delete #files
insert #files exec (@cmd)
-- now buld the restore
select @cmd = null ,
@s = ''
while @s < (select max(lname) from #files)
begin
select top 1 @s = lname, @t = type from #files where lname > @s order by lname
select @cmd = coalesce(@cmd + ',move ', '') + '''' + @s
+ ''' to ''' + case when @t = 'D' then @DataPath else @LogPath end
+ @s + ''''
end
select @cmd = 'restore database ' + @dbname + ' from disk = ''' + @SourcePath + @filename + ''' with move ' + @cmd + ', NORECOVERY' -- + ', standby = ''' + @localpath + 'standby.fil'''
exec (@cmd)
end
else if @filename like '%^Log^_%' escape '^'
begin
-- restore a log backup
select @cmd = 'restore log ' + @dbname + ' from disk = ''' + @SourcePath + @filename + ''' with NORECOVERY'
exec (@cmd)
end
-- move to archive
select @cmd = 'move ' + @SourcePath + @filename + ' ' + @archivePath + @filename
exec master..xp_cmdshell @cmd
delete #dir where s = @filename
end
-- now set to correct recovey mode
if @recover = 'recover'
begin
select @cmd = 'restore database ' + @dbname + ' with recovery'
exec (@cmd)
end
end
GO
home