diff --git a/README.md b/README.md index 8caaad4c..e874b611 100644 --- a/README.md +++ b/README.md @@ -462,7 +462,7 @@ Parameters include: * @Debug - default 0. When 1, we print out messages of what we're doing in the messages tab of SSMS. * @StopAt NVARCHAR(14) - pass in a date time to stop your restores at a time like '20170508201501'. This doesn't use the StopAt parameter for the restore command - it simply stops restoring logs that would have this date/time's contents in it. (For example, if you're taking backups every 15 minutes on the hour, and you pass in 9:05 AM as part of the restore time, the restores would stop at your last log backup that doesn't include 9:05AM's data - but it won't restore right up to 9:05 AM.) * @SkipBackupsAlreadyInMsdb - default 0. When set to 1, we check MSDB for the most recently restored backup from this log path, and skip all backup files prior to that. Useful if you're pulling backups from across a slow network and you don't want to wait to check the restore header of each backup. - +* @EnableBroker - default 0. When set to 1, we run RESTORE WITH ENABLE_BROKER, enabling the service broker. Unless specified, the service broker is disabled on restore even if it was enabled when the backup was taken. For information about how this works, see [Tara Kizer's white paper on Log Shipping 2.0 with Google Compute Engine.](https://www.brentozar.com/archive/2017/03/new-white-paper-build-sql-server-disaster-recovery-plan-google-compute-engine/) diff --git a/sp_DatabaseRestore.sql b/sp_DatabaseRestore.sql index 49c9408e..6463d410 100755 --- a/sp_DatabaseRestore.sql +++ b/sp_DatabaseRestore.sql @@ -12,28 +12,28 @@ IF OBJECT_ID('dbo.sp_DatabaseRestore') IS NULL EXEC ('CREATE PROCEDURE dbo.sp_DatabaseRestore AS RETURN 0;'); GO ALTER PROCEDURE [dbo].[sp_DatabaseRestore] - @Database NVARCHAR(128) = NULL, - @RestoreDatabaseName NVARCHAR(128) = NULL, - @BackupPathFull NVARCHAR(260) = NULL, - @BackupPathDiff NVARCHAR(260) = NULL, + @Database NVARCHAR(128) = NULL, + @RestoreDatabaseName NVARCHAR(128) = NULL, + @BackupPathFull NVARCHAR(260) = NULL, + @BackupPathDiff NVARCHAR(260) = NULL, @BackupPathLog NVARCHAR(260) = NULL, - @MoveFiles BIT = 1, - @MoveDataDrive NVARCHAR(260) = NULL, - @MoveLogDrive NVARCHAR(260) = NULL, + @MoveFiles BIT = 1, + @MoveDataDrive NVARCHAR(260) = NULL, + @MoveLogDrive NVARCHAR(260) = NULL, @MoveFilestreamDrive NVARCHAR(260) = NULL, - @MoveFullTextCatalogDrive NVARCHAR(260) = NULL, + @MoveFullTextCatalogDrive NVARCHAR(260) = NULL, @BufferCount INT = NULL, @MaxTransferSize INT = NULL, @BlockSize INT = NULL, - @TestRestore BIT = 0, - @RunCheckDB BIT = 0, + @TestRestore BIT = 0, + @RunCheckDB BIT = 0, @RestoreDiff BIT = 0, - @ContinueLogs BIT = 0, + @ContinueLogs BIT = 0, @StandbyMode BIT = 0, @StandbyUndoPath NVARCHAR(MAX) = NULL, - @RunRecovery BIT = 0, + @RunRecovery BIT = 0, @ForceSimpleRecovery BIT = 0, - @ExistingDBAction tinyint = 0, + @ExistingDBAction TINYINT = 0, @StopAt NVARCHAR(14) = NULL, @OnlyLogsAfter NVARCHAR(14) = NULL, @SimpleFolderEnumeration BIT = 0, @@ -44,13 +44,14 @@ ALTER PROCEDURE [dbo].[sp_DatabaseRestore] @KeepCdc BIT = 0, @Execute CHAR(1) = Y, @FileExtensionDiff NVARCHAR(128) = NULL, - @Debug INT = 0, + @Debug INT = 0, @Help BIT = 0, @Version VARCHAR(30) = NULL OUTPUT, @VersionDate DATETIME = NULL OUTPUT, @VersionCheckMode BIT = 0, @FileNamePrefix NVARCHAR(260) = NULL, - @RunStoredProcAfterRestore NVARCHAR(260) = NULL + @RunStoredProcAfterRestore NVARCHAR(260) = NULL, + @EnableBroker BIT = 0 AS SET NOCOUNT ON; SET STATISTICS XML OFF; @@ -64,43 +65,43 @@ BEGIN RETURN; END; - + IF @Help = 1 BEGIN PRINT ' /* sp_DatabaseRestore from http://FirstResponderKit.org - + This script will restore a database from a given file path. - + To learn more, visit http://FirstResponderKit.org where you can download new versions for free, watch training videos on how it works, get more info on the findings, contribute your own code, and more. - + Known limitations of this version: - Only Microsoft-supported versions of SQL Server. Sorry, 2005 and 2000. - Tastes awful with marmite. - + Unknown limitations of this version: - None. (If we knew them, they would be known. Duh.) - + Changes - for the full list of improvements and fixes in this version, see: https://github.com/BrentOzarULTD/SQL-Server-First-Responder-Kit/ - + MIT License - + Copyright (c) Brent Ozar Unlimited - + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -108,119 +109,119 @@ BEGIN LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - + */ '; - + PRINT ' /* - EXEC dbo.sp_DatabaseRestore - @Database = ''LogShipMe'', - @BackupPathFull = ''D:\Backup\SQL2016PROD1A\LogShipMe\FULL\'', - @BackupPathLog = ''D:\Backup\SQL2016PROD1A\LogShipMe\LOG\'', - @ContinueLogs = 0, + EXEC dbo.sp_DatabaseRestore + @Database = ''LogShipMe'', + @BackupPathFull = ''D:\Backup\SQL2016PROD1A\LogShipMe\FULL\'', + @BackupPathLog = ''D:\Backup\SQL2016PROD1A\LogShipMe\LOG\'', + @ContinueLogs = 0, @RunRecovery = 0; - - EXEC dbo.sp_DatabaseRestore - @Database = ''LogShipMe'', - @BackupPathFull = ''D:\Backup\SQL2016PROD1A\LogShipMe\FULL\'', - @BackupPathLog = ''D:\Backup\SQL2016PROD1A\LogShipMe\LOG\'', - @ContinueLogs = 1, + + EXEC dbo.sp_DatabaseRestore + @Database = ''LogShipMe'', + @BackupPathFull = ''D:\Backup\SQL2016PROD1A\LogShipMe\FULL\'', + @BackupPathLog = ''D:\Backup\SQL2016PROD1A\LogShipMe\LOG\'', + @ContinueLogs = 1, @RunRecovery = 0; - - EXEC dbo.sp_DatabaseRestore - @Database = ''LogShipMe'', - @BackupPathFull = ''D:\Backup\SQL2016PROD1A\LogShipMe\FULL\'', - @BackupPathLog = ''D:\Backup\SQL2016PROD1A\LogShipMe\LOG\'', - @ContinueLogs = 1, + + EXEC dbo.sp_DatabaseRestore + @Database = ''LogShipMe'', + @BackupPathFull = ''D:\Backup\SQL2016PROD1A\LogShipMe\FULL\'', + @BackupPathLog = ''D:\Backup\SQL2016PROD1A\LogShipMe\LOG\'', + @ContinueLogs = 1, @RunRecovery = 1; - - EXEC dbo.sp_DatabaseRestore - @Database = ''LogShipMe'', - @BackupPathFull = ''D:\Backup\SQL2016PROD1A\LogShipMe\FULL\'', - @BackupPathLog = ''D:\Backup\SQL2016PROD1A\LogShipMe\LOG\'', - @ContinueLogs = 0, + + EXEC dbo.sp_DatabaseRestore + @Database = ''LogShipMe'', + @BackupPathFull = ''D:\Backup\SQL2016PROD1A\LogShipMe\FULL\'', + @BackupPathLog = ''D:\Backup\SQL2016PROD1A\LogShipMe\LOG\'', + @ContinueLogs = 0, @RunRecovery = 1; - - EXEC dbo.sp_DatabaseRestore - @Database = ''LogShipMe'', - @BackupPathFull = ''D:\Backup\SQL2016PROD1A\LogShipMe\FULL\'', + + EXEC dbo.sp_DatabaseRestore + @Database = ''LogShipMe'', + @BackupPathFull = ''D:\Backup\SQL2016PROD1A\LogShipMe\FULL\'', @BackupPathDiff = ''D:\Backup\SQL2016PROD1A\LogShipMe\DIFF\'', - @BackupPathLog = ''D:\Backup\SQL2016PROD1A\LogShipMe\LOG\'', + @BackupPathLog = ''D:\Backup\SQL2016PROD1A\LogShipMe\LOG\'', @RestoreDiff = 1, - @ContinueLogs = 0, + @ContinueLogs = 0, @RunRecovery = 1; - - EXEC dbo.sp_DatabaseRestore - @Database = ''LogShipMe'', - @BackupPathFull = ''\\StorageServer\LogShipMe\FULL\'', + + EXEC dbo.sp_DatabaseRestore + @Database = ''LogShipMe'', + @BackupPathFull = ''\\StorageServer\LogShipMe\FULL\'', @BackupPathDiff = ''\\StorageServer\LogShipMe\DIFF\'', - @BackupPathLog = ''\\StorageServer\LogShipMe\LOG\'', + @BackupPathLog = ''\\StorageServer\LogShipMe\LOG\'', @RestoreDiff = 1, - @ContinueLogs = 0, + @ContinueLogs = 0, @RunRecovery = 1, @TestRestore = 1, @RunCheckDB = 1, @Debug = 0; - EXEC dbo.sp_DatabaseRestore - @Database = ''LogShipMe'', - @BackupPathFull = ''\\StorageServer\LogShipMe\FULL\'', + EXEC dbo.sp_DatabaseRestore + @Database = ''LogShipMe'', + @BackupPathFull = ''\\StorageServer\LogShipMe\FULL\'', @BackupPathLog = ''\\StorageServer\LogShipMe\LOG\'', @StandbyMode = 1, @StandbyUndoPath = ''D:\Data\'', - @ContinueLogs = 1, + @ContinueLogs = 1, @RunRecovery = 0, @Debug = 0; --Restore just through the latest DIFF, ignoring logs, and using a custom ".dif" file extension - EXEC dbo.sp_DatabaseRestore - @Database = ''LogShipMe'', - @BackupPathFull = ''D:\Backup\SQL2016PROD1A\LogShipMe\FULL\'', + EXEC dbo.sp_DatabaseRestore + @Database = ''LogShipMe'', + @BackupPathFull = ''D:\Backup\SQL2016PROD1A\LogShipMe\FULL\'', @BackupPathDiff = ''D:\Backup\SQL2016PROD1A\LogShipMe\DIFF\'', @RestoreDiff = 1, @FileExtensionDiff = ''dif'', - @ContinueLogs = 0, + @ContinueLogs = 0, @RunRecovery = 1; -- Restore from stripped backup set when multiple paths are used. This example will restore stripped full backup set along with stripped transactional logs set from multiple backup paths - EXEC dbo.sp_DatabaseRestore - @Database = ''DBA'', - @BackupPathFull = ''D:\Backup1\DBA\FULL,D:\Backup2\DBA\FULL'', - @BackupPathLog = ''D:\Backup1\DBA\LOG,D:\Backup2\DBA\LOG'', + EXEC dbo.sp_DatabaseRestore + @Database = ''DBA'', + @BackupPathFull = ''D:\Backup1\DBA\FULL,D:\Backup2\DBA\FULL'', + @BackupPathLog = ''D:\Backup1\DBA\LOG,D:\Backup2\DBA\LOG'', @StandbyMode = 0, - @ContinueLogs = 1, + @ContinueLogs = 1, @RunRecovery = 0, @Debug = 0; - + --This example will restore the latest differential backup, and stop transaction logs at the specified date time. It will execute and print debug information. - EXEC dbo.sp_DatabaseRestore - @Database = ''DBA'', - @BackupPathFull = ''\\StorageServer\LogShipMe\FULL\'', + EXEC dbo.sp_DatabaseRestore + @Database = ''DBA'', + @BackupPathFull = ''\\StorageServer\LogShipMe\FULL\'', @BackupPathDiff = ''\\StorageServer\LogShipMe\DIFF\'', - @BackupPathLog = ''\\StorageServer\LogShipMe\LOG\'', + @BackupPathLog = ''\\StorageServer\LogShipMe\LOG\'', @RestoreDiff = 1, - @ContinueLogs = 0, + @ContinueLogs = 0, @RunRecovery = 1, @StopAt = ''20170508201501'', @Debug = 1; --This example will NOT execute the restore. Commands will be printed in a copy/paste ready format only - EXEC dbo.sp_DatabaseRestore - @Database = ''DBA'', - @BackupPathFull = ''\\StorageServer\LogShipMe\FULL\'', + EXEC dbo.sp_DatabaseRestore + @Database = ''DBA'', + @BackupPathFull = ''\\StorageServer\LogShipMe\FULL\'', @BackupPathDiff = ''\\StorageServer\LogShipMe\DIFF\'', - @BackupPathLog = ''\\StorageServer\LogShipMe\LOG\'', + @BackupPathLog = ''\\StorageServer\LogShipMe\LOG\'', @RestoreDiff = 1, - @ContinueLogs = 0, + @ContinueLogs = 0, @RunRecovery = 1, @TestRestore = 1, @RunCheckDB = 1, @Debug = 0, @Execute = ''N''; '; - - RETURN; + + RETURN; END; -- Get the SQL Server version number because the columns returned by RESTORE commands vary by version @@ -237,7 +238,7 @@ BEGIN RETURN; END; -BEGIN TRY +BEGIN TRY DECLARE @CurrentDatabaseContext AS VARCHAR(128) = (SELECT DB_NAME()); DECLARE @CommandExecuteCheck VARCHAR(315) @@ -269,16 +270,16 @@ DECLARE @cmd NVARCHAR(4000) = N'', --Holds xp_cmdshell command @LogRestoreRanking INT = 1, --Holds Log iteration # when multiple paths & backup files are being stripped @LogFirstLSN NUMERIC(25, 0), --Holds first LSN in log backup headers @LogLastLSN NUMERIC(25, 0), --Holds last LSN in log backup headers - @LogLastNameInMsdbAS NVARCHAR(MAX) = N'', -- Holds last TRN file name already restored + @LogLastNameInMsdbAS NVARCHAR(MAX) = N'', -- Holds last TRN file name already restored @FileListParamSQL NVARCHAR(4000) = N'', --Holds INSERT list for #FileListParameters @BackupParameters NVARCHAR(500) = N'', --Used to save BlockSize, MaxTransferSize and BufferCount @RestoreDatabaseID SMALLINT, --Holds DB_ID of @RestoreDatabaseName - @UnquotedRestoreDatabaseName nvarchar(128); --Holds the unquoted @RestoreDatabaseName + @UnquotedRestoreDatabaseName NVARCHAR(128); --Holds the unquoted @RestoreDatabaseName DECLARE @FileListSimple TABLE ( - BackupFile NVARCHAR(255) NOT NULL, - depth int NOT NULL, - [file] int NOT NULL + BackupFile NVARCHAR(255) NOT NULL, + depth INT NOT NULL, + [file] INT NOT NULL ); DECLARE @FileList TABLE ( @@ -377,8 +378,8 @@ CREATE TABLE #Headers KeyAlgorithm NVARCHAR(32), EncryptorThumbprint VARBINARY(20), EncryptorType NVARCHAR(32), - LastValidRestoreTime DATETIME, - TimeZone NVARCHAR(32), + LastValidRestoreTime DATETIME, + TimeZone NVARCHAR(32), CompressionAlgorithm NVARCHAR(32), -- -- Seq added to retain order by @@ -540,7 +541,7 @@ SET @UnquotedRestoreDatabaseName = PARSENAME(@RestoreDatabaseName,1); IF NOT EXISTS (SELECT * FROM sys.configurations WHERE name = 'xp_cmdshell' AND value_in_use = 1) SET @SimpleFolderEnumeration = 1; -SET @HeadersSQL = +SET @HeadersSQL = N'INSERT INTO #Headers WITH (TABLOCK) (BackupName, BackupDescription, BackupType, ExpirationDate, Compressed, Position, DeviceType, UserName, ServerName ,DatabaseName, DatabaseVersion, DatabaseCreationDate, BackupSize, FirstLSN, LastLSN, CheckpointLSN, DatabaseBackupLSN @@ -549,7 +550,7 @@ N'INSERT INTO #Headers WITH (TABLOCK) ,RecoveryForkID, Collation, FamilyGUID, HasBulkLoggedData, IsSnapshot, IsReadOnly, IsSingleUser, HasBackupChecksums ,IsDamaged, BeginsLogChain, HasIncompleteMetaData, IsForceOffline, IsCopyOnly, FirstRecoveryForkID, ForkPointLSN ,RecoveryModel, DifferentialBaseLSN, DifferentialBaseGUID, BackupTypeDescription, BackupSetGUID, CompressedBackupSize'; - + IF @MajorVersion >= 11 SET @HeadersSQL += NCHAR(13) + NCHAR(10) + N', Containment'; @@ -566,7 +567,7 @@ IF @BackupPathFull IS NOT NULL BEGIN DECLARE @CurrentBackupPathFull NVARCHAR(255); - -- Split CSV string logic has taken from Ola Hallengren's :) + -- Split CSV string logic has taken from Ola Hallengren's :) WITH BackupPaths ( StartPosition, EndPosition, PathItem ) @@ -593,7 +594,7 @@ BEGIN IF @@rowcount = 0 BREAK; IF @SimpleFolderEnumeration = 1 - BEGIN -- Get list of files + BEGIN -- Get list of files INSERT INTO @FileListSimple (BackupFile, depth, [file]) EXEC master.sys.xp_dirtree @CurrentBackupPathFull, 1, 1; INSERT @FileList (BackupPath,BackupFile) SELECT @CurrentBackupPathFull, BackupFile FROM @FileListSimple; DELETE FROM @FileListSimple; @@ -605,12 +606,12 @@ BEGIN BEGIN IF @cmd IS NULL PRINT '@cmd is NULL for @CurrentBackupPathFull'; PRINT @cmd; - END; + END; INSERT INTO @FileList (BackupFile) EXEC master.sys.xp_cmdshell @cmd; UPDATE @FileList SET BackupPath = @CurrentBackupPathFull WHERE BackupPath IS NULL; END; - + IF @Debug = 1 BEGIN SELECT BackupPath, BackupFile FROM @FileList; @@ -628,8 +629,8 @@ BEGIN BEGIN /*Full Sanity check folders*/ IF ( - SELECT COUNT(*) - FROM @FileList AS fl + SELECT COUNT(*) + FROM @FileList AS fl WHERE fl.BackupFile = 'The system cannot find the path specified.' OR fl.BackupFile = 'File Not Found' ) = 1 @@ -638,8 +639,8 @@ BEGIN RETURN; END; IF ( - SELECT COUNT(*) - FROM @FileList AS fl + SELECT COUNT(*) + FROM @FileList AS fl WHERE fl.BackupFile = 'Access is denied.' ) = 1 BEGIN @@ -647,13 +648,13 @@ BEGIN RETURN; END; IF ( - SELECT COUNT(*) - FROM @FileList AS fl + SELECT COUNT(*) + FROM @FileList AS fl ) = 1 - AND + AND ( - SELECT COUNT(*) - FROM @FileList AS fl + SELECT COUNT(*) + FROM @FileList AS fl WHERE fl.BackupFile IS NULL ) = 1 BEGIN @@ -661,8 +662,8 @@ BEGIN RETURN; END IF ( - SELECT COUNT(*) - FROM @FileList AS fl + SELECT COUNT(*) + FROM @FileList AS fl WHERE fl.BackupFile = 'The user name or password is incorrect.' ) = 1 BEGIN @@ -687,8 +688,8 @@ BEGIN AND BackupFile LIKE N'%' + @Database + N'%' AND (REPLACE( RIGHT( REPLACE( BackupFile, RIGHT( BackupFile, PATINDEX( '%_[0-9][0-9]%', REVERSE( BackupFile ) ) ), '' ), 18 ), '_', '' ) > @StopAt); END; - - -- Find latest full backup + + -- Find latest full backup SELECT @LastFullBackup = MAX(BackupFile) FROM @FileList WHERE BackupFile LIKE N'%.bak' @@ -717,11 +718,11 @@ BEGIN FROM @FileList WHERE LEFT( BackupFile, LEN( BackupFile ) - PATINDEX( '%[_]%', REVERSE( BackupFile ) ) ) = LEFT( @LastFullBackup, LEN( @LastFullBackup ) - PATINDEX( '%[_]%', REVERSE( @LastFullBackup ) ) ) AND PATINDEX( '%[_]%', REVERSE( @LastFullBackup ) ) <= 7 -- there is a 1 or 2 digit index at the end of the string which indicates split backups. Ola only supports up to 64 file split. - ORDER BY REPLACE( RIGHT( REPLACE( BackupFile, RIGHT( BackupFile, PATINDEX( '%_[0-9][0-9]%', REVERSE( BackupFile ) ) ), '' ), 16 ), '_', '' ) DESC; + ORDER BY REPLACE( RIGHT( REPLACE( BackupFile, RIGHT( BackupFile, PATINDEX( '%_[0-9][0-9]%', REVERSE( BackupFile ) ) ), '' ), 16 ), '_', '' ) DESC; -- File list can be obtained by running RESTORE FILELISTONLY of any file from the given BackupSet therefore we do not have to cater for split backups when building @FileListParamSQL - SET @FileListParamSQL = + SET @FileListParamSQL = N'INSERT INTO #FileListParameters WITH (TABLOCK) (LogicalName, PhysicalName, Type, FileGroupName, Size, MaxSize, FileID, CreateLSN, DropLSN ,UniqueID, ReadOnlyLSN, ReadWriteLSN, BackupSizeInBytes, SourceBlockSize, FileGroupID, LogGroupGUID @@ -755,7 +756,7 @@ BEGIN SELECT '@FileList' AS table_name, BackupPath, BackupFile FROM @FileList WHERE BackupFile IS NOT NULL; END - --get the backup completed data so we can apply tlogs from that point forwards + --get the backup completed data so we can apply tlogs from that point forwards SET @sql = REPLACE(@HeadersSQL, N'{Path}', @CurrentBackupPathFull + @LastFullBackup); IF @Debug = 1 @@ -813,7 +814,7 @@ BEGIN SELECT @MoveOption = @MoveOption + N', MOVE ''' + Files.LogicalName + N''' TO ''' + Files.TargetPhysicalName + '''' FROM Files WHERE Files.TargetPhysicalName <> Files.PhysicalName; - + IF @Debug = 1 PRINT @MoveOption END; @@ -833,7 +834,7 @@ BEGIN END; IF @Debug IN (0, 1) AND @Execute = 'Y' BEGIN - IF DATABASEPROPERTYEX(@UnquotedRestoreDatabaseName,'STATUS') != 'RESTORING' + IF DATABASEPROPERTYEX(@UnquotedRestoreDatabaseName,'STATUS') != 'RESTORING' BEGIN EXECUTE @sql = [dbo].[CommandExecute] @DatabaseContext=N'master', @Command = @sql, @CommandType = 'ALTER DATABASE SINGLE_USER', @Mode = 1, @DatabaseName = @UnquotedRestoreDatabaseName, @LogToTable = 'Y', @Execute = 'Y'; END @@ -848,7 +849,7 @@ BEGIN BEGIN RAISERROR('Killing connections', 0, 1) WITH NOWAIT; SET @sql = N'/* Kill connections */' + NCHAR(13); - SELECT + SELECT @sql = @sql + N'KILL ' + CAST(spid as nvarchar(5)) + N';' + NCHAR(13) FROM --database_ID was only added to sys.dm_exec_sessions in SQL Server 2012 but we need to support older @@ -866,7 +867,7 @@ BEGIN IF @ExistingDBAction = 3 BEGIN RAISERROR('Dropping database', 0, 1) WITH NOWAIT; - + SET @sql = N'DROP DATABASE ' + @RestoreDatabaseName + NCHAR(13); IF @Debug = 1 OR @Execute = 'N' BEGIN @@ -888,7 +889,7 @@ BEGIN END; IF @Debug IN (0, 1) AND @Execute = 'Y' BEGIN - IF DATABASEPROPERTYEX(@UnquotedRestoreDatabaseName,'STATUS') != 'RESTORING' + IF DATABASEPROPERTYEX(@UnquotedRestoreDatabaseName,'STATUS') != 'RESTORING' BEGIN EXECUTE @sql = [dbo].[CommandExecute] @DatabaseContext=N'master', @Command = @sql, @CommandType = 'OFFLINE DATABASE', @Mode = 1, @DatabaseName = @UnquotedRestoreDatabaseName, @LogToTable = 'Y', @Execute = 'Y'; END @@ -909,7 +910,7 @@ BEGIN IF @ContinueLogs = 0 BEGIN IF @Execute = 'Y' RAISERROR('@ContinueLogs set to 0', 0, 1) WITH NOWAIT; - + /* now take split backups into account */ IF (SELECT COUNT(*) FROM #SplitFullBackups) > 0 BEGIN @@ -949,7 +950,7 @@ BEGIN IF @sql IS NULL PRINT '@sql is NULL for RESTORE DATABASE: @BackupPathFull, @LastFullBackup, @MoveOption'; PRINT @sql; END; - + IF @Debug IN (0, 1) AND @Execute = 'Y' EXECUTE @sql = [dbo].[CommandExecute] @DatabaseContext=N'master', @Command = @sql, @CommandType = 'RESTORE DATABASE', @Mode = 1, @DatabaseName = @UnquotedRestoreDatabaseName, @LogToTable = 'Y', @Execute = 'Y'; @@ -957,44 +958,44 @@ BEGIN --setting the @BackupDateTime to a numeric string so that it can be used in comparisons SET @BackupDateTime = REPLACE( RIGHT( REPLACE( @LastFullBackup, RIGHT( @LastFullBackup, PATINDEX( '%_[0-9][0-9]%', REVERSE( @LastFullBackup ) ) ), '' ), 16 ), '_', '' ); - - SELECT @FullLastLSN = CAST(LastLSN AS NUMERIC(25, 0)) FROM #Headers WHERE BackupType = 1; + + SELECT @FullLastLSN = CAST(LastLSN AS NUMERIC(25, 0)) FROM #Headers WHERE BackupType = 1; IF @Debug = 1 BEGIN IF @BackupDateTime IS NULL PRINT '@BackupDateTime is NULL for REPLACE: @LastFullBackup'; PRINT @BackupDateTime; - END; - + END; + END; ELSE BEGIN - + SELECT @DatabaseLastLSN = CAST(f.redo_start_lsn AS NUMERIC(25, 0)) FROM master.sys.databases d JOIN master.sys.master_files f ON d.database_id = f.database_id WHERE d.name = SUBSTRING(@RestoreDatabaseName, 2, LEN(@RestoreDatabaseName) - 2) AND f.file_id = 1; - + END; END; IF @BackupPathFull IS NULL AND @ContinueLogs = 1 BEGIN - + SELECT @DatabaseLastLSN = CAST(f.redo_start_lsn AS NUMERIC(25, 0)) FROM master.sys.databases d JOIN master.sys.master_files f ON d.database_id = f.database_id WHERE d.name = SUBSTRING(@RestoreDatabaseName, 2, LEN(@RestoreDatabaseName) - 2) AND f.file_id = 1; - + END; IF @BackupPathDiff IS NOT NULL -BEGIN +BEGIN DELETE FROM @FileList; DELETE FROM @FileListSimple; DELETE FROM @PathItem; DECLARE @CurrentBackupPathDiff NVARCHAR(512); - -- Split CSV string logic has taken from Ola Hallengren's :) + -- Split CSV string logic has taken from Ola Hallengren's :) WITH BackupPaths ( StartPosition, EndPosition, PathItem ) @@ -1021,7 +1022,7 @@ BEGIN IF @@rowcount = 0 BREAK; IF @SimpleFolderEnumeration = 1 - BEGIN -- Get list of files + BEGIN -- Get list of files INSERT INTO @FileListSimple (BackupFile, depth, [file]) EXEC master.sys.xp_dirtree @CurrentBackupPathDiff, 1, 1; INSERT @FileList (BackupPath,BackupFile) SELECT @CurrentBackupPathDiff, BackupFile FROM @FileListSimple; DELETE FROM @FileListSimple; @@ -1033,11 +1034,11 @@ BEGIN BEGIN IF @cmd IS NULL PRINT '@cmd is NULL for @CurrentBackupPathDiff'; PRINT @cmd; - END; + END; INSERT INTO @FileList (BackupFile) EXEC master.sys.xp_cmdshell @cmd; UPDATE @FileList SET BackupPath = @CurrentBackupPathDiff WHERE BackupPath IS NULL; END; - + IF @Debug = 1 BEGIN SELECT BackupPath,BackupFile FROM @FileList WHERE BackupFile IS NOT NULL; @@ -1046,8 +1047,8 @@ BEGIN BEGIN /*Full Sanity check folders*/ IF ( - SELECT COUNT(*) - FROM @FileList AS fl + SELECT COUNT(*) + FROM @FileList AS fl WHERE fl.BackupFile = 'The system cannot find the path specified.' ) = 1 BEGIN @@ -1055,8 +1056,8 @@ BEGIN RETURN; END; IF ( - SELECT COUNT(*) - FROM @FileList AS fl + SELECT COUNT(*) + FROM @FileList AS fl WHERE fl.BackupFile = 'Access is denied.' ) = 1 BEGIN @@ -1064,8 +1065,8 @@ BEGIN RETURN; END; IF ( - SELECT COUNT(*) - FROM @FileList AS fl + SELECT COUNT(*) + FROM @FileList AS fl WHERE fl.BackupFile = 'The user name or password is incorrect.' ) = 1 BEGIN @@ -1075,7 +1076,7 @@ BEGIN END; END /*End folder sanity check*/ - -- Find latest diff backup + -- Find latest diff backup IF @FileExtensionDiff IS NULL BEGIN IF @Execute = 'Y' OR @Debug = 1 RAISERROR('No @FileExtensionDiff given, assuming "bak".', 0, 1) WITH NOWAIT; @@ -1091,7 +1092,7 @@ BEGIN (@StopAt IS NULL OR REPLACE( RIGHT( REPLACE( BackupFile, RIGHT( BackupFile, PATINDEX( '%_[0-9][0-9]%', REVERSE( BackupFile ) ) ), '' ), 16 ), '_', '' ) <= @StopAt) ORDER BY BackupFile DESC; - -- Load FileList data into Temp Table sorted by DateTime Stamp desc + -- Load FileList data into Temp Table sorted by DateTime Stamp desc SELECT BackupPath, BackupFile INTO #SplitDiffBackups FROM @FileList WHERE LEFT( BackupFile, LEN( BackupFile ) - PATINDEX( '%[_]%', REVERSE( BackupFile ) ) ) = LEFT( @LastDiffBackup, LEN( @LastDiffBackup ) - PATINDEX( '%[_]%', REVERSE( @LastDiffBackup ) ) ) @@ -1128,49 +1129,49 @@ BEGIN END ELSE IF (SELECT COUNT(*) FROM #SplitDiffBackups) > 0 SET @sql = @sql + ', STANDBY = ''' + @StandbyUndoPath + @Database + 'Undo.ldf''' + NCHAR(13) + NCHAR(10); - ELSE + ELSE SET @sql = N'RESTORE DATABASE ' + @RestoreDatabaseName + N' FROM DISK = ''' + @BackupPathDiff + @LastDiffBackup + N''' WITH STANDBY = ''' + @StandbyUndoPath + @Database + 'Undo.ldf''' + @BackupParameters + @MoveOption + NCHAR(13) + NCHAR(10); END; IF @Debug = 1 OR @Execute = 'N' BEGIN IF @sql IS NULL PRINT '@sql is NULL for RESTORE DATABASE: @BackupPathDiff, @LastDiffBackup'; PRINT @sql; - END; + END; IF @Debug IN (0, 1) AND @Execute = 'Y' EXECUTE @sql = [dbo].[CommandExecute] @DatabaseContext=N'master', @Command = @sql, @CommandType = 'RESTORE DATABASE', @Mode = 1, @DatabaseName = @UnquotedRestoreDatabaseName, @LogToTable = 'Y', @Execute = 'Y'; - - --get the backup completed data so we can apply tlogs from that point forwards + + --get the backup completed data so we can apply tlogs from that point forwards SET @sql = REPLACE(@HeadersSQL, N'{Path}', @CurrentBackupPathDiff + @LastDiffBackup); - + IF @Debug = 1 BEGIN IF @sql IS NULL PRINT '@sql is NULL for REPLACE: @CurrentBackupPathDiff, @LastDiffBackup'; PRINT @sql; - END; - + END; + EXECUTE (@sql); IF @Debug = 1 BEGIN SELECT '#Headers' AS table_name, @LastDiffBackup AS DiffbackupFile, * FROM #Headers AS h WHERE h.BackupType = 5; END - - --set the @BackupDateTime to the date time on the most recent differential + + --set the @BackupDateTime to the date time on the most recent differential SET @BackupDateTime = ISNULL( @LastDiffBackupDateTime, @BackupDateTime ); IF @Debug = 1 BEGIN IF @BackupDateTime IS NULL PRINT '@BackupDateTime is NULL for REPLACE: @LastDiffBackupDateTime'; PRINT @BackupDateTime; - END; + END; SELECT @DiffLastLSN = CAST(LastLSN AS NUMERIC(25, 0)) - FROM #Headers - WHERE BackupType = 5; + FROM #Headers + WHERE BackupType = 5; END; IF @DiffLastLSN IS NULL BEGIN SET @DiffLastLSN=@FullLastLSN END -END +END IF @BackupPathLog IS NOT NULL @@ -1180,7 +1181,7 @@ BEGIN DELETE FROM @PathItem; DECLARE @CurrentBackupPathLog NVARCHAR(512); - -- Split CSV string logic has taken from Ola Hallengren's :) + -- Split CSV string logic has taken from Ola Hallengren's :) WITH BackupPaths ( StartPosition, EndPosition, PathItem ) @@ -1206,7 +1207,7 @@ BEGIN IF @@rowcount = 0 BREAK; IF @SimpleFolderEnumeration = 1 - BEGIN -- Get list of files + BEGIN -- Get list of files INSERT INTO @FileListSimple (BackupFile, depth, [file]) EXEC master.sys.xp_dirtree @BackupPathLog, 1, 1; INSERT @FileList (BackupPath, BackupFile) SELECT @CurrentBackupPathLog, BackupFile FROM @FileListSimple; DELETE FROM @FileListSimple; @@ -1218,12 +1219,12 @@ BEGIN BEGIN IF @cmd IS NULL PRINT '@cmd is NULL for @CurrentBackupPathLog'; PRINT @cmd; - END; + END; INSERT INTO @FileList (BackupFile) EXEC master.sys.xp_cmdshell @cmd; UPDATE @FileList SET BackupPath = @CurrentBackupPathLog WHERE BackupPath IS NULL; END; - + IF @SimpleFolderEnumeration = 1 BEGIN /*Check what we can*/ @@ -1237,8 +1238,8 @@ BEGIN BEGIN /*Full Sanity check folders*/ IF ( - SELECT COUNT(*) - FROM @FileList AS fl + SELECT COUNT(*) + FROM @FileList AS fl WHERE fl.BackupFile = 'The system cannot find the path specified.' OR fl.BackupFile = 'File Not Found' ) = 1 @@ -1248,8 +1249,8 @@ BEGIN END; IF ( - SELECT COUNT(*) - FROM @FileList AS fl + SELECT COUNT(*) + FROM @FileList AS fl WHERE fl.BackupFile = 'Access is denied.' ) = 1 BEGIN @@ -1258,13 +1259,13 @@ BEGIN END; IF ( - SELECT COUNT(*) - FROM @FileList AS fl + SELECT COUNT(*) + FROM @FileList AS fl ) = 1 - AND + AND ( - SELECT COUNT(*) - FROM @FileList AS fl + SELECT COUNT(*) + FROM @FileList AS fl WHERE fl.BackupFile IS NULL ) = 1 BEGIN @@ -1273,8 +1274,8 @@ BEGIN END IF ( - SELECT COUNT(*) - FROM @FileList AS fl + SELECT COUNT(*) + FROM @FileList AS fl WHERE fl.BackupFile = 'The user name or password is incorrect.' ) = 1 BEGIN @@ -1282,11 +1283,11 @@ BEGIN RETURN; END; END; - END + END /*End folder sanity check*/ IF @Debug = 1 -BEGIN +BEGIN SELECT * FROM @FileList WHERE BackupFile IS NOT NULL; END @@ -1300,12 +1301,12 @@ BEGIN WHERE physical_device_name like @BackupPathLog + '%' AND rh.destination_database_name = @UnquotedRestoreDatabaseName ORDER BY physical_device_name DESC - + IF @Debug = 1 BEGIN SELECT 'Keeping LOG backups with name > : ' + @LogLastNameInMsdbAS END - + DELETE fl FROM @FileList AS fl WHERE fl.BackupPath + fl.BackupFile <= @LogLastNameInMsdbAS @@ -1315,20 +1316,20 @@ END IF (@OnlyLogsAfter IS NOT NULL) BEGIN - + IF @Execute = 'Y' OR @Debug = 1 RAISERROR('@OnlyLogsAfter is NOT NULL, deleting from @FileList', 0, 1) WITH NOWAIT; - + DELETE fl FROM @FileList AS fl WHERE BackupFile LIKE N'%.trn' - AND BackupFile LIKE N'%' + @Database + N'%' + AND BackupFile LIKE N'%' + @Database + N'%' AND REPLACE( RIGHT( REPLACE( fl.BackupFile, RIGHT( fl.BackupFile, PATINDEX( '%_[0-9][0-9]%', REVERSE( fl.BackupFile ) ) ), '' ), 16 ), '_', '' ) < @OnlyLogsAfter; - + END -- Check for log backups IF(@BackupDateTime IS NOT NULL AND @BackupDateTime <> '') - BEGIN + BEGIN DELETE FROM @FileList WHERE BackupFile LIKE N'%.trn' AND BackupFile LIKE N'%' + @Database + N'%' @@ -1353,7 +1354,7 @@ IF (@LogRecoveryOption = N'') IF (@StopAt IS NOT NULL) BEGIN - + IF @Execute = 'Y' OR @Debug = 1 RAISERROR('@StopAt is NOT NULL, deleting from @FileList', 0, 1) WITH NOWAIT; IF LEN(@StopAt) <> 14 OR PATINDEX('%[^0-9]%', @StopAt) > 0 @@ -1373,18 +1374,18 @@ BEGIN IF @BackupDateTime = @StopAt BEGIN - IF @Debug = 1 + IF @Debug = 1 BEGIN RAISERROR('@StopAt is the end time of a FULL backup, no log files will be restored.', 0, 1) WITH NOWAIT; END END ELSE - BEGIN + BEGIN DECLARE @ExtraLogFile NVARCHAR(255) SELECT TOP 1 @ExtraLogFile = fl.BackupFile FROM @FileList AS fl WHERE BackupFile LIKE N'%.trn' - AND BackupFile LIKE N'%' + @Database + N'%' + AND BackupFile LIKE N'%' + @Database + N'%' AND REPLACE( RIGHT( REPLACE( fl.BackupFile, RIGHT( fl.BackupFile, PATINDEX( '%_[0-9][0-9]%', REVERSE( fl.BackupFile ) ) ), '' ), 16 ), '_', '' ) > @StopAt ORDER BY BackupFile; END @@ -1402,11 +1403,11 @@ BEGIN -- If this is a split backup, @ExtraLogFile contains only the first split backup file, either _1.trn or _01.trn -- Change @ExtraLogFile to the max split backup file, then delete all log files greater than this SET @ExtraLogFile = REPLACE(REPLACE(@ExtraLogFile, '_1.trn', '_9.trn'), '_01.trn', '_64.trn') - + DELETE fl FROM @FileList AS fl WHERE BackupFile LIKE N'%.trn' - AND BackupFile LIKE N'%' + @Database + N'%' + AND BackupFile LIKE N'%' + @Database + N'%' AND fl.BackupFile > @ExtraLogFile END END @@ -1417,38 +1418,38 @@ SELECT BackupPath,BackupFile,DENSE_RANK() OVER (ORDER BY REPLACE( RIGHT( REPLACE FROM @FileList WHERE BackupFile IS NOT NULL; --- Loop through all the files for the database +-- Loop through all the files for the database WHILE 1 = 1 BEGIN - -- Get the TOP record to use in "Restore HeaderOnly/FileListOnly" statement + -- Get the TOP record to use in "Restore HeaderOnly/FileListOnly" statement SELECT TOP 1 @CurrentBackupPathLog = BackupPath, @BackupFile = BackupFile FROM #SplitLogBackups WHERE DenseRank = @LogRestoreRanking; IF @@rowcount = 0 BREAK; IF @i = 1 - + BEGIN SET @sql = REPLACE(@HeadersSQL, N'{Path}', @CurrentBackupPathLog + @BackupFile); - + IF @Debug = 1 BEGIN IF @sql IS NULL PRINT '@sql is NULL for REPLACE: @HeadersSQL, @CurrentBackupPathLog, @BackupFile'; PRINT @sql; - END; - + END; + EXECUTE (@sql); - - SELECT TOP 1 @LogFirstLSN = CAST(FirstLSN AS NUMERIC(25, 0)), - @LogLastLSN = CAST(LastLSN AS NUMERIC(25, 0)) - FROM #Headers + + SELECT TOP 1 @LogFirstLSN = CAST(FirstLSN AS NUMERIC(25, 0)), + @LogLastLSN = CAST(LastLSN AS NUMERIC(25, 0)) + FROM #Headers WHERE BackupType = 2; - + IF (@ContinueLogs = 0 AND @LogFirstLSN <= @FullLastLSN AND @FullLastLSN <= @LogLastLSN AND @RestoreDiff = 0) OR (@ContinueLogs = 1 AND @LogFirstLSN <= @DatabaseLastLSN AND @DatabaseLastLSN < @LogLastLSN AND @RestoreDiff = 0) SET @i = 2; - + IF (@ContinueLogs = 0 AND @LogFirstLSN <= @DiffLastLSN AND @DiffLastLSN <= @LogLastLSN AND @RestoreDiff = 1) OR (@ContinueLogs = 1 AND @LogFirstLSN <= @DatabaseLastLSN AND @DatabaseLastLSN < @LogLastLSN AND @RestoreDiff = 1) SET @i = 2; - + DELETE FROM #Headers WHERE BackupType = 2; @@ -1469,7 +1470,7 @@ WHERE BackupFile IS NOT NULL; SET @sql = N'RESTORE LOG ' + @RestoreDatabaseName + N' FROM ' + STUFF( (SELECT CHAR( 10 ) + ',DISK=''' + BackupPath + BackupFile + '''' - FROM #SplitLogBackups + FROM #SplitLogBackups WHERE DenseRank = @LogRestoreRanking ORDER BY BackupFile FOR XML PATH ('')), @@ -1479,17 +1480,17 @@ WHERE BackupFile IS NOT NULL; END; ELSE SET @sql = N'RESTORE LOG ' + @RestoreDatabaseName + N' FROM DISK = ''' + @CurrentBackupPathLog + @BackupFile + N''' WITH ' + @LogRecoveryOption + NCHAR(13) + NCHAR(10); - + IF @Debug = 1 OR @Execute = 'N' BEGIN IF @sql IS NULL PRINT '@sql is NULL for RESTORE LOG: @RestoreDatabaseName, @CurrentBackupPathLog, @BackupFile'; PRINT @sql; - END; - + END; + IF @Debug IN (0, 1) AND @Execute = 'Y' EXECUTE @sql = [dbo].[CommandExecute] @DatabaseContext=N'master', @Command = @sql, @CommandType = 'RESTORE LOG', @Mode = 1, @DatabaseName = @UnquotedRestoreDatabaseName, @LogToTable = 'Y', @Execute = 'Y'; END; - + SET @LogRestoreRanking += 1; END; @@ -1500,21 +1501,24 @@ WHERE BackupFile IS NOT NULL; END END --- Put database in a useable state +-- Put database in a useable state IF @RunRecovery = 1 BEGIN SET @sql = N'RESTORE DATABASE ' + @RestoreDatabaseName + N' WITH RECOVERY'; - + IF @KeepCdc = 1 SET @sql = @sql + N', KEEP_CDC'; + IF @EnableBroker = 1 + SET @sql = @sql + N', ENABLE_BROKER'; + SET @sql = @sql + NCHAR(13); IF @Debug = 1 OR @Execute = 'N' BEGIN IF @sql IS NULL PRINT '@sql is NULL for RESTORE DATABASE: @RestoreDatabaseName'; PRINT @sql; - END; + END; IF @Debug IN (0, 1) AND @Execute = 'Y' EXECUTE @sql = [dbo].[CommandExecute] @DatabaseContext=N'master', @Command = @sql, @CommandType = 'RECOVER DATABASE', @Mode = 1, @DatabaseName = @UnquotedRestoreDatabaseName, @LogToTable = 'Y', @Execute = 'Y'; @@ -1529,23 +1533,23 @@ IF @ForceSimpleRecovery = 1 BEGIN IF @sql IS NULL PRINT '@sql is NULL for SET RECOVERY SIMPLE: @RestoreDatabaseName'; PRINT @sql; - END; + END; IF @Debug IN (0, 1) AND @Execute = 'Y' EXECUTE @sql = [dbo].[CommandExecute] @DatabaseContext=N'master', @Command = @sql, @CommandType = 'SIMPLE LOGGING', @Mode = 1, @DatabaseName = @UnquotedRestoreDatabaseName, @LogToTable = 'Y', @Execute = 'Y'; - END; + END; -- Run checkdb against this database IF @RunCheckDB = 1 BEGIN SET @sql = N'DBCC CHECKDB (' + @RestoreDatabaseName + N') WITH NO_INFOMSGS, ALL_ERRORMSGS, DATA_PURITY;'; - + IF @Debug = 1 OR @Execute = 'N' BEGIN IF @sql IS NULL PRINT '@sql is NULL for Run Integrity Check: @RestoreDatabaseName'; PRINT @sql; - END; - + END; + IF @Debug IN (0, 1) AND @Execute = 'Y' EXECUTE @sql = [dbo].[CommandExecute] @DatabaseContext=N'master', @Command = @sql, @CommandType = 'DBCC CHECKDB', @Mode = 1, @DatabaseName = @UnquotedRestoreDatabaseName, @LogToTable = 'Y', @Execute = 'Y'; END; @@ -1608,7 +1612,7 @@ IF @DatabaseOwner IS NOT NULL END; -- Link a user entry in the sys.database_principals system catalog view in the restored database to a SQL Server login of the same name -IF @FixOrphanUsers = 1 +IF @FixOrphanUsers = 1 BEGIN SET @sql = N' -- Fixup Orphan Users by setting database user sid to match login sid @@ -1627,7 +1631,7 @@ SELECT ''ALTER USER ['' + d.name + ''] WITH LOGIN = ['' + d.name + '']; '' SELECT @FixOrphansSql = (SELECT SqlToExecute AS [text()] FROM @OrphanUsers FOR XML PATH (''''), TYPE).value(''text()[1]'',''NVARCHAR(MAX)''); -IF @FixOrphansSql IS NULL +IF @FixOrphansSql IS NULL PRINT ''No orphan users require a sid fixup.''; ELSE BEGIN @@ -1643,7 +1647,7 @@ END;' IF @Debug IN (0, 1) AND @Execute = 'Y' EXECUTE [dbo].[CommandExecute] @DatabaseContext = 'master', @Command = @sql, @CommandType = 'UPDATE', @Mode = 1, @DatabaseName = @UnquotedRestoreDatabaseName, @LogToTable = 'Y', @Execute = 'Y'; - END; + END; IF @RunStoredProcAfterRestore IS NOT NULL AND LEN(LTRIM(@RunStoredProcAfterRestore)) > 0 BEGIN @@ -1655,7 +1659,7 @@ BEGIN IF @sql IS NULL PRINT '@sql is NULL when building for @RunStoredProcAfterRestore' PRINT @sql END - + IF @RunRecovery = 0 BEGIN PRINT 'Unable to run Run Stored Procedure After Restore as database is not recovered. Run command again with @RunRecovery = 1' @@ -1671,13 +1675,13 @@ END IF @TestRestore = 1 BEGIN SET @sql = N'DROP DATABASE ' + @RestoreDatabaseName + NCHAR(13); - + IF @Debug = 1 OR @Execute = 'N' BEGIN IF @sql IS NULL PRINT '@sql is NULL for DROP DATABASE: @RestoreDatabaseName'; PRINT @sql; - END; - + END; + IF @Debug IN (0, 1) AND @Execute = 'Y' EXECUTE @sql = [dbo].[CommandExecute] @DatabaseContext=N'master',@Command = @sql, @CommandType = 'DROP DATABASE', @Mode = 1, @DatabaseName = @UnquotedRestoreDatabaseName, @LogToTable = 'Y', @Execute = 'Y';