This script will generate a restore statement with supporting MOVE operations to a new directory structure.
2016-11-22
1,210 reads
This script will generate a restore statement with supporting MOVE operations to a new directory structure.
SET NOCOUNT ON
GO
/******************************************************************************
**
** Name: Quick-n-Diry restore script generator.sql
**
** Description: Quickly generate restore script from a backup device.
**
** Generate a restore script with the proper move
** statements automatically.
**
** Change values for:
**
** @i_db_name -- Database name to restore as.
** @FilePath -- Backup directory
** @BackupFileName -- Backup filename
** @i_data_location -- Restore to path.
**
**
** Return values: 0 - Success
** -1 - Error
**
**
** Author: G. Rayburn
**
** Date: 01/27/2006
**
*******************************************************************************
** Modification History
*******************************************************************************
**
** Initial Creation: 01/27/2006 G. Rayburn
** 03/16/2007 G. Rayburn -- Fixed ALTER issue for SQL2000.
** 01/25/2008 G. Rayburn -- Added RESTORE LABELONLY code.
**
*******************************************************************************
**
******************************************************************************/DECLARE @retcode int
, @l_bkup_file_nm varchar(520)
, @l_bkup_file_location varchar(520)
, @l_index int
, @l_exec_stmt varchar(8000)
, @l_Old_file_location varchar(520)
, @l_New_file_location varchar(520)
, @l_file_nm varchar(520)
, @l_file_location varchar(520)
, @l_LogicalName varchar(256)
, @l_exec_stmt_len int
, @i_backup varchar(8000)
, @i_db_name sysname
, @i_data_location varchar(8000)
, @RestoreLABELONLY varchar(1024)
, @RestoreLABELONLYCMD varchar(2048)
, @FilePath varchar(1024)
, @BackupFileName varchar(128)
, @FamilyCount int
, @CurrLoopOp int
, @DynString_01 varchar(8000)
, @RestoreStr_01 varchar(512)
, @RestoreStr_02 varchar(512)
, @FileExistCheck varchar(1024)
-- Change these variables:
SET @i_db_name = 'YourDBName'
SET @FilePath = '\\Server\Share\'
SET @BackupFileName = 'FooDB_20080125_01.BAK'
SET @i_data_location = 'D:\MSSQL\Data'
-- Don't change.
SET @l_index = 0
SET @l_bkup_file_nm = '''' + @FilePath + @BackupFileName + ''''
SET @FileExistCheck = @FilePath + @BackupFileName
SET @RestoreLABELONLY = 'RESTORE LABELONLY FROM DISK = '
SET @RestoreLABELONLYCMD = @RestoreLABELONLY + '''' + @FilePath + @BackupFileName + ''''
-- -- Verify backup file exists.
EXEC master..xp_fileexist @FileExistCheck, @retcode OUTPUT
IF (@retcode) = 0
BEGIN
PRINT @FileExistCheck + ' does not exist, exiting process.'
PRINT ''
RETURN
END
-- Gather # of backup files and build FROM DISK string:
CREATE TABLE #_RESTORE_LABELONLY
(
[MediaName] nvarchar(128)
, [MediaSetId] uniqueidentifier
, [FamilyCount] int
, [FamilySequenceNumber] int
, [MediaFamilyId] uniqueidentifier
, [MediaSequenceNumber] int
, [MediaLabelPresent] tinyint
, [MediaDescription] nvarchar(255)
, [SoftwareName] nvarchar(128)
, [SoftwareVendorId] int
, [MediaDate] datetime
, [Mirror_Count] int
)
INSERT INTO #_RESTORE_LABELONLY
EXEC (@RestoreLABELONLYCMD)
SET @FamilyCount = (SELECT FamilyCount FROM #_RESTORE_LABELONLY)
SET @CurrLoopOp = 2 -- Have to start at 2 because 1 is being used by @RestoreStr_01.
SET @DynString_01 = ''
SELECT @RestoreStr_01 = 'FROM DISK = ''' + @FilePath + @BackupFileName + '''' + char(10) + char(13)
, @RestoreStr_02 = ', DISK = ''' + @FilePath
WHILE @CurrLoopOp <= @FamilyCount
BEGIN
SET @DynString_01 = @DynString_01 + @RestoreStr_02 + STUFF(@BackupFileName,LEN(@BackupFileName)-4,1,CONVERT(char(1),@CurrLoopOp)) + '''' + char(10) + char(13)
SET @CurrLoopOp = @CurrLoopOp + 1
IF @CurrLoopOp > @FamilyCount
BREAK
ELSE
CONTINUE
END
-- Get information on logical names and paths from the backup itself.
IF EXISTS (SELECT * FROM tempdb..sysobjects WHERE NAME LIKE '#bkup_file_details%' )
DROP TABLE #bkup_file_details
SET NOCOUNT ON
CREATE TABLE #bkup_file_details
(
LogicalName nvarchar(128)
,Old_PhysicalName nvarchar(128)
,[Type] char(1)
,FileGroupName nvarchar(128)
,[Size] numeric(20,0)
,[MaxSize] numeric(20,0)
,FileID bigint
,CreateLSN numeric(25,0)
,DropLSN numeric(25,0) NULL
,UniqueID uniqueidentifier
,ReadOnlyLSN numeric(25,0)
,ReadWriteLSN numeric(25,0)
,BackupSizeInByte bigint
,SourceBlockSize int
,FilegroupID int
,LogGroupGUID uniqueidentifier NULL
,DifferentialBaseLSN numeric(25,0)
,DifferentialbaseGUID uniqueidentifier
,IsReadOnly bit
,IsPresent bit
)
-- Get number and names of the files in the backup.
SELECT @l_exec_stmt = 'RESTORE FILELISTONLY FROM DISK = ''' + @FilePath + @BackupFileName + ''''
INSERT INTO #bkup_file_details
EXEC (@l_exec_stmt)
-- Add New_PhysicalName for cursor later on.
ALTER TABLE #bkup_file_details
ADD New_PhysicalName varchar(128)
-- Update New_PhysicalName with the target path.
SELECT @retcode = 0
DECLARE file_details scroll CURSOR
FOR SELECT Old_PhysicalName
FROM #bkup_file_details
OPEN file_details
WHILE @retcode = 0
BEGIN
FETCH NEXT FROM file_details
INTO @l_Old_file_location
IF(@@fetch_status <> 0)
BREAK
SELECT @l_file_nm = @l_Old_file_location
SELECT @l_index = charindex('\', @l_file_nm)
WHILE(@l_index <> 0)
BEGIN
SELECT @l_file_nm = right(@l_file_nm, datalength(@l_file_nm)- @l_index)
SELECT @l_index = charindex('\', @l_file_nm)
END
SELECT @l_New_file_location = @i_data_location + '\' + @i_db_name + '_' + @l_file_nm
UPDATE #bkup_file_details
SET New_PhysicalName = @l_New_file_location
WHERE Old_PhysicalName = @l_Old_file_location
END
CLOSE file_details
DEALLOCATE file_details
-- Generate first portion of the restore statement.
SELECT @l_exec_stmt = 'RESTORE DATABASE [' + @i_db_name + ']
' + @RestoreStr_01 + @DynString_01 + '
WITH RECOVERY
, REPLACE
, STATS = 5'
-- Generate the MOVE statements and append them to the first.
DECLARE file_details scroll CURSOR
FOR SELECT LogicalName
, New_PhysicalName
FROM #bkup_file_details
OPEN file_details
WHILE @retcode = 0
BEGIN
FETCH next FROM file_details
INTO @l_LogicalName,
@l_file_location
IF(@@fetch_status <> 0)
BREAK
SELECT @l_exec_stmt = @l_exec_stmt + '
, MOVE ''' + @l_LogicalName + ''' TO ''' + @l_file_location + ''''
END
CLOSE file_details
DEALLOCATE file_details
-- DEBUG:
PRINT ''
PRINT (@l_exec_stmt)
PRINT ''
DROP TABLE #_RESTORE_LABELONLY