Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
Lumbago
Norsk Yak Master
3271 Posts |
Posted - 2008-04-30 : 08:02:29
|
This script was originally posted by Michael Valentine Jones in this thread -> http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=71665. I simply added the functionality to script the restore command for all backup-files in a given folder + the posibility to alter the location of the data/log-files./*Create Restore Command from multiple DB Backup FilesOriginally created by Michael Valentine Jones, SQLTeam.com- Modified by Henning Frettem*/SET NOCOUNT ONGODECLARE @backup_path nvarchar(500), @totCount int, @Current int, @dirCmd varchar(200), @Filename varchar(200), @tab varchar(1), @cr varchar(2), @new_data_path varchar(500), @new_log_path varchar(500)SELECT @backup_path = 'D:\Backups\' --> Folder where full database backupfiles are locatedSELECT @new_data_path = 'D:\new_data_path\' --> Optional, leave blank to use the default from the backup fileSELECT @new_log_path = 'D:\new_log_path\' --> Optional, leave blank to use the default from the backup fileCREATE TABLE #BackupFiles ( ID INT IDENTITY(1, 1) PRIMARY KEY CLUSTERED, [Filename] VARCHAR(500))SET @dirCmd = 'dir /b "' + @backup_path + '" 'INSERT INTO #BackupFiles ([Filename])EXEC xp_cmdshell @dirCmd--> Delete excess row in #BackupFilesDELETE #BackupFiles WHERE [Filename] IS NULLCREATE TABLE #header ( BackupName nvarchar(128) NULL, BackupDescription nvarchar(128) NULL, BackupType int NOT NULL, ExpirationDate datetime NULL, Compressed int NOT NULL, Position int NOT NULL, DeviceType int NOT NULL, UserName nvarchar(128) NOT NULL, ServerName nvarchar(128) NOT NULL, DatabaseName nvarchar(128) NOT NULL, DatabaseVersion int NOT NULL, DatabaseCreationDate datetime NOT NULL, BackupSize decimal(28,0) NOT NULL, FirstLsn decimal(28,0) NOT NULL, LastLsn decimal(28,0) NOT NULL, CheckpointLsn decimal(28,0) NOT NULL, DatabaseBackupLsn decimal(28,0) NOT NULL, BackupStartDate datetime NOT NULL, BackupFinishDate datetime NOT NULL, SortOrder int NOT NULL, CodePage int NOT NULL, UnicodeLocaleId int NOT NULL, UnicodeComparisonStyle int NOT NULL, CompatibilityLevel int NOT NULL, SoftwareVendorId int NULL, SoftwareVersionMajor int NULL, SoftwareVersionMinor int NULL, SoftwareVersionBuild int NULL, MachineName nvarchar(128) NOT NULL, Flags int NULL, BindingID uniqueidentifier NULL, RecoveryForkID uniqueidentifier NULL, Collation nvarchar(128) NULL, Seq int NOT NULL identity(1,1),)CREATE TABLE #filelist ( LogicalName nvarchar(128) NOT NULL, PhysicalName nvarchar(128) NOT NULL, Type nvarchar(10) NOT NULL, FileGroupName nvarchar(128) NULL, Size decimal(28,0) NOT NULL, MAXSize decimal(28,0) NOT NULL, Seq int NOT NULL identity(1,1),)SET @totCount = (SELECT COUNT(*) FROM #BackupFiles)SET @Current = 1SELECT @tab = char(9), @cr = char(13)+Char(10)--> Loop through the files that hasn't been restored before and restore them one by oneWHILE (@Current <= @totCount AND @totCount > 0) BEGIN SELECT @Filename = [Filename] FROM #BackupFiles WHERE ID = @Current INSERT INTO #header EXEC ('RESTORE HeaderOnly FROM DISK = ''' + @backup_path + @Filename + '''') INSERT INTO #filelist EXEC ('RESTORE FilelistOnly FROM DISK = ''' + @backup_path + @Filename + '''') --> Replace the old data file path with a new one if specified IF @new_data_path <> '' UPDATE #filelist SET PhysicalName = @new_data_path + right(physicalname, CHARINDEX('\',REVERSE(physicalname))-1) WHERE Type = 'D' --> Replace the old log file path with a new one if specified IF @new_data_path <> '' UPDATE #filelist SET PhysicalName = @new_log_path + right(physicalname, CHARINDEX('\',REVERSE(physicalname))-1) WHERE Type = 'L' --> Print restore script SELECT [--Restore--] = CASE WHEN a.Seq = 1 THEN @cr + @cr + 'RESTORE DATABASE ' + c.DatabaseName + @cr + 'FROM DISK =' + @cr + @tab + '''' + @backup_path + @Filename + '''' + @cr + 'WITH' + @cr ELSE '' END + @tab + 'MOVE ''' + a.LogicalName + ''' TO ''' + a.PhysicalName+''' ,' + CASE WHEN a.Seq = b.Seq THEN @cr + @tab + 'REPLACE, STATS = 5 , NORECOVERY' ELSE '' END FROM #filelist a CROSS JOIN (SELECT Seq = MAX(b1.Seq) FROM #filelist b1 ) b CROSS JOIN (SELECT DatabaseName = MAX(c1.DatabaseName) FROM #header c1) c ORDER BY a.Seq SET @Current = @Current + 1 TRUNCATE TABLE #header TRUNCATE TABLE #filelist ENDDROP TABLE #headerDROP TABLE #filelistDROP TABLE #BackupFiles --Lumbago |
|
JohnnyG
Starting Member
1 Post |
Posted - 2008-08-08 : 09:41:32
|
Would it be possible to update the script to do a recursive loop thru the backup directory to get any additional backup files in subdirectories underneath the original backup path? |
|
|
Lumbago
Norsk Yak Master
3271 Posts |
Posted - 2009-03-13 : 10:33:08
|
Wow...just noticed the reply to this thread now...6 months late [:S]But yes, this is actually *really* simple!! Just add a /s to the dir command:SET @dirCmd = 'dir /b /s "' + @backup_path + '" '- Lumbago |
|
|
cshah1
Constraint Violating Yak Guru
347 Posts |
Posted - 2009-04-10 : 15:50:03
|
Lumbago, in SQL 2005 when I run your script getting this errorMsg 213, Level 16, State 7, Line 1Insert Error: Column name or number of supplied values does not match table definition??? |
|
|
Lumbago
Norsk Yak Master
3271 Posts |
Posted - 2009-04-14 : 03:07:59
|
Script for 2005:/*Create Restore Command from multiple DB Backup FilesOriginally created by Michael Valentine Jones, SQLTeam.com- Modified by Henning FrettemREMEMBER TO INCREASE MAX CHARACTER OUTPUT FOR EACH COLUMN BEFORE RUNNING THIS SCRIPT!!*/SET NOCOUNT ONGODECLARE @backup_path varchar(500), @totCount int, @Current int, @dirCmd varchar(200), @Filename varchar(200), @tab varchar(1), @cr varchar(2), @new_data_path varchar(500), @new_log_path varchar(500)SELECT @backup_path = 'D:\Backups\' --> Folder where full database backupfiles are locatedSELECT @new_data_path = 'D:\new_data_file_path\' --> Optional, leave blank to use the default from the backup fileSELECT @new_log_path = 'D:\new_log_file_path\' --> Optional, leave blank to use the default from the backup fileCREATE TABLE #BackupFiles ( ID INT IDENTITY(1, 1) PRIMARY KEY CLUSTERED, [Filename] VARCHAR(500))SET @dirCmd = 'dir /b "' + @backup_path + 'Full*.bak" 'INSERT INTO #BackupFiles ([Filename])EXEC xp_cmdshell @dirCmd--> Delete excess row in #BackupFilesDELETE #BackupFiles WHERE [Filename] IS NULL OR [Filename] NOT LIKE '%.bak'CREATE TABLE #header ( BackupName varchar(128) NULL, BackupDescription varchar(255) NULL, BackupType smallint NULL, ExpirationDate datetime NULL, Compressed tinyint NULL, Position smallint NULL, DeviceType tinyint NULL, UserName varchar(128) NULL, ServerName varchar(128) NULL, DatabaseName varchar(128) NULL, DatabaseVersion int NULL, DatabaseCreationDate datetime NULL, BackupSize numeric(20,0) NULL, FirstLSN numeric(25,0) NULL, LastLSN numeric(25,0) NULL, CheckpointLSN numeric(25,0) NULL, DatabaseBackupLSN numeric(25,0) NULL, BackupStartDate datetime NULL, BackupFinishDate datetime NULL, SortOrder smallint NULL, CodePage smallint NULL, UnicodeLocaleId int NULL, UnicodeComparisonStyle int NULL, CompatibilityLevel tinyint NULL, SoftwareVendorId int NULL, SoftwareVersionMajor int NULL, SoftwareVersionMinor int NULL, SoftwareVersionBuild int NULL, MachineName varchar(128) NULL, Flags int NULL, BindingID uniqueidentifier NULL, RecoveryForkID uniqueidentifier NULL, Collation varchar(128) NULL, FamilyGUID uniqueidentifier NULL, HasBulkLoggedData bit NULL, IsSnapshot bit NULL, IsReadOnly bit NULL, IsSingleUser bit NULL, HasBackupChecksums bit NULL, IsDamaged bit NULL, BeginsLogChain bit NULL, HasIncompleteMetaData bit NULL, IsForceOffline bit NULL, IsCopyOnly bit NULL, FirstRecoveryForkID uniqueidentifier NULL, ForkPointLSN numeric(25,0) NULL, RecoveryModel varchar(60) NULL, DifferentialBaseLSN numeric(25,0) NULL, DifferentialBaseGUID uniqueidentifier NULL, BackupTypeDescription varchar(60) NULL, BackupSetGUID uniqueidentifier NULL, Seq int NOT NULL identity(1,1))CREATE TABLE #filelist ( LogicalName varchar(128) NULL, PhysicalName varchar(260) NULL, Type char(1) NULL, FileGroupName varchar(128) NULL, Size numeric(20,0) NULL, MaxSize numeric(20,0) NULL, FileID bigint NULL, CreateLSN numeric(25,0) NULL, DropLSN numeric(25,0) NULL, UniqueID uniqueidentifier NULL, ReadOnlyLSN numeric(25,0) NULL, ReadWriteLSN numeric(25,0) NULL, BackupSizeInBytes bigint NULL, SourceBlockSize int NULL, FileGroupID int NULL, LogGroupGUID uniqueidentifier NULL, DifferentialBaseLSN numeric(25,0) NULL, DifferentialBaseGUID uniqueidentifier NULL, IsReadOnly bit NULL, IsPresent bit NULL, Seq int NOT NULL identity(1,1))SET @totCount = (SELECT COUNT(*) FROM #BackupFiles)SET @Current = 1SELECT @tab = char(9), @cr = char(13)+Char(10)--> Loop through the files that hasn't been restored before and restore them one by oneWHILE (@Current <= @totCount AND @totCount > 0) BEGIN SELECT @Filename = [Filename] FROM #BackupFiles WHERE ID = @Current INSERT INTO #header EXEC ('RESTORE HeaderOnly FROM DISK = ''' + @backup_path + @Filename + '''') INSERT INTO #filelist EXEC ('RESTORE FilelistOnly FROM DISK = ''' + @backup_path + @Filename + '''') --> Replace the old data file path with a new one if specified IF @new_data_path <> '' UPDATE #filelist SET PhysicalName = @new_data_path + right(physicalname, CHARINDEX('\',REVERSE(physicalname))-1) WHERE Type = 'D' --> Replace the old log file path with a new one if specified IF @new_data_path <> '' UPDATE #filelist SET PhysicalName = @new_log_path + right(physicalname, CHARINDEX('\',REVERSE(physicalname))-1) WHERE Type = 'L' --> Print restore script SELECT [--Restore--] = CASE WHEN a.Seq = 1 THEN @cr + @cr + 'RESTORE DATABASE [' + c.DatabaseName + ']' + @cr + 'FROM DISK =' + @cr + @tab + '''' + @backup_path + @Filename + '''' + @cr + 'WITH' + @cr ELSE '' END + @tab + 'MOVE ''' + a.LogicalName + ''' TO ''' + a.PhysicalName + ''' ,' + CASE WHEN a.Seq = b.Seq THEN @cr + @tab + 'REPLACE, STATS = 5 , --NORECOVERY' ELSE '' END FROM #filelist a CROSS JOIN (SELECT Seq = MAX(b1.Seq) FROM #filelist b1 ) b CROSS JOIN (SELECT DatabaseName = MAX(c1.DatabaseName) FROM #header c1) c ORDER BY a.Seq SET @Current = @Current + 1 TRUNCATE TABLE #header TRUNCATE TABLE #filelistENDDROP TABLE #headerDROP TABLE #filelistDROP TABLE #BackupFiles - Lumbago |
|
|
Lumbago
Norsk Yak Master
3271 Posts |
Posted - 2011-01-06 : 04:22:41
|
2008-version:/*Create Restore Command from multiple DB Backup FilesOriginally created by Michael Valentine Jones, SQLTeam.com- Modified by Henning FrettemREMEMBER TO INCREASE MAX CHARACTER OUTPUT FOR EACH COLUMN BEFORE RUNNING THIS SCRIPT!!*/SET NOCOUNT ONGODECLARE @backup_path varchar(500), @totCount int, @Current int, @dirCmd varchar(200), @Filename varchar(200), @DatabaseName varchar(200), @CreateDBFolder bit, @tab varchar(1), @cr varchar(2), @new_data_path varchar(500), @new_data_path2 varchar(500), @new_log_path varchar(500), @new_log_path2 varchar(500)SELECT @backup_path = 'e:\full_Backups\' --> Folder where full database backupfiles are locatedSELECT @new_data_path = 'E:\MSSQL2005\Data\' --> Optional, leave blank to use the default from the backup fileSELECT @new_log_path = 'F:\MSSQL2005\Logs\' --> Optional, leave blank to use the default from the backup fileSELECT @CreateDBFolder = 1 --> If 1 is specidied the data/log files will be placed in a separate folder named after the databaseCREATE TABLE #BackupFiles ( ID INT IDENTITY(1, 1) PRIMARY KEY CLUSTERED, [Filename] VARCHAR(500))SET @dirCmd = 'dir /b "' + @backup_path + '*full.bak" 'INSERT INTO #BackupFiles ([Filename])EXEC xp_cmdshell @dirCmd--> Delete excess row in #BackupFilesDELETE #BackupFiles WHERE [Filename] IS NULL OR [Filename] NOT LIKE '%.bak'CREATE TABLE #header ( BackupName nvarchar(128), BackupDescription nvarchar(255), BackupType smallint, ExpirationDate datetime, Compressed bit, Position smallint, DeviceType tinyint, UserName nvarchar(128), ServerName nvarchar(128), DatabaseName nvarchar(128), DatabaseVersion int, DatabaseCreationDate datetime, BackupSize numeric(20,0), FirstLSN numeric(25,0), LastLSN numeric(25,0), CheckpointLSN numeric(25,0), DatabaseBackupLSN numeric(25,0), BackupStartDate datetime, BackupFinishDate datetime, SortOrder smallint, CodePage smallint, UnicodeLocaleId int, UnicodeComparisonStyle int, CompatibilityLevel tinyint, SoftwareVendorId int, SoftwareVersionMajor int, SoftwareVersionMinor int, SoftwareVersionBuild int, MachineName nvarchar(128), Flags int, BindingID uniqueidentifier, RecoveryForkID uniqueidentifier, Collation nvarchar(128), FamilyGUID uniqueidentifier, HasBulkLoggedData bit, IsSnapshot bit, IsReadOnly bit, IsSingleUser bit, HasBackupChecksums bit, IsDamaged bit, BeginsLogChain bit, HasIncompleteMetaData bit, IsForceOffline bit, IsCopyOnly bit, FirstRecoveryForkID uniqueidentifier, ForkPointLSN numeric(25,0) NULL, RecoveryModel nvarchar(60), DifferentialBaseLSN numeric(25,0) NULL, DifferentialBaseGUID uniqueidentifier, BackupTypeDescription nvarchar(60), BackupSetGUID uniqueidentifier NULL, CompressedBackupSize bigint, Seq int NOT NULL identity(1,1) ) CREATE TABLE #filelist ( LogicalName nvarchar(128), PhysicalName nvarchar(260), 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) NULL, ReadWriteLSN numeric(25,0) NULL, BackupSizeInBytes bigint, SourceBlockSize int, FileGroupID int, LogGroupGUID uniqueidentifier NULL, DifferentialBaseLSN numeric(25,0) NULL, DifferentialBaseGUID uniqueidentifier, IsReadOnly bit, IsPresent bit, TDEThumbprint varbinary(32), Seq int NOT NULL identity(1,1) )SET @totCount = (SELECT COUNT(*) FROM #BackupFiles)SET @Current = 1SELECT @tab = char(9), @cr = char(13)+Char(10)--> Loop through the files that hasn't been restored before and restore them one by oneWHILE (@Current <= @totCount AND @totCount > 0) BEGIN SELECT @Filename = [Filename] FROM #BackupFiles WHERE ID = @Current INSERT INTO #header EXEC ('RESTORE HeaderOnly FROM DISK = ''' + @backup_path + @Filename + '''') INSERT INTO #filelist EXEC ('RESTORE FilelistOnly FROM DISK = ''' + @backup_path + @Filename + '''') SELECT @DatabaseName = Databasename, @new_data_path2 = CASE WHEN @CreateDBFolder = 1 THEN @new_data_path + DatabaseName + '\' ELSE @new_data_path END, @new_log_path2 = CASE WHEN @CreateDBFolder = 1 THEN @new_log_path + DatabaseName + '\' ELSE @new_log_path END FROM #header --> Replace the old data file path with a new one if specified IF @new_data_path2 <> '' UPDATE #filelist SET PhysicalName = @new_data_path2 + right(physicalname, CHARINDEX('\',REVERSE(physicalname))-1) WHERE Type = 'D' --> Replace the old log file path with a new one if specified IF @new_log_path2 <> '' UPDATE #filelist SET PhysicalName = @new_log_path2 + right(physicalname, CHARINDEX('\',REVERSE(physicalname))-1) WHERE Type = 'L' --> Print restore script SELECT [--Restore--] = CASE WHEN a.Seq = 1 AND @CreateDBFolder = 1 THEN @cr + 'EXEC xp_cmdshell ''md ' + @new_data_path2 + '''' + @cr + 'EXEC xp_cmdshell ''md ' + @new_log_path2 + '''' ELSE '' END + CASE WHEN a.Seq = 1 THEN @cr + @cr + 'RESTORE DATABASE [' + c.DatabaseName + ']' + @cr + 'FROM DISK =' + @cr + @tab + '''' + @backup_path + @Filename + '''' + @cr + 'WITH' + @cr ELSE '' END + @tab + 'MOVE ''' + a.LogicalName + ''' TO ''' + a.PhysicalName + ''' ,' + CASE WHEN a.Seq = b.Seq THEN @cr + @tab + 'REPLACE, STATS = 5, --NORECOVERY' ELSE '' END FROM #filelist a CROSS JOIN (SELECT Seq = MAX(b1.Seq) FROM #filelist b1 ) b CROSS JOIN (SELECT DatabaseName = MAX(c1.DatabaseName) FROM #header c1) c ORDER BY a.Seq SET @Current = @Current + 1 TRUNCATE TABLE #header TRUNCATE TABLE #filelistENDDROP TABLE #headerDROP TABLE #filelistDROP TABLE #BackupFiles - LumbagoMy blog (yes, I have a blog now! just not that much content yet) -> www.thefirstsql.com |
|
|
|
|
|
|
|