Backup & Restore Script with a Move

Ok, I’ll admit it. I like scripts that are handy and do things.  Especially if the scripts make my life easier.

Now, not every environment is the same.  Instances get configured differently or things change just due to the nature of the business.  In a previous life I would routinely have to backup a database and restore it to another server.  However, the server I was using to restore to had a different drive configuration.  It happens.  Anyway, I wanted a script that would give me

  • A backup statement
  • A restore statement with the appropriate MOVE switch

This would allow me to easily execute the backup statement and then on the target server execute the restore statement.  Since the restore statement already had the appropriate MOVE switch provided, I didn’t have to manually compose the statement.

First, we will declare some variables just to make things a little cleaner and easier

DECLARE @date CHAR(8)
SET @date = (SELECT CONVERT(char(8), GETDATE(), 112))

DECLARE @path VARCHAR(125)
SET @path = '\\UNCPath\Folder\'

Next, we’ll use a CTE to get the database name(s) and the file paths.  The CTE is what does the work to create the MOVE switch.

;WITH MoveCmdCTE ( DatabaseName, MoveCmd )
          AS ( SELECT DISTINCT
                        DB_NAME(database_id) ,
                        STUFF((SELECT   ' ' + CHAR(13)+', MOVE ''' + name + ''''
                                        + CASE Type
                                            WHEN 0 THEN ' TO ''D:\SQLData\'
                                            ELSE ' TO ''E:\SQLTLogs\'
                                          END
                                        + REVERSE(LEFT(REVERSE(physical_name),
                                                       CHARINDEX('\',
                                                              REVERSE(physical_name),
                                                              1) - 1)) + ''''
                               FROM     sys.master_files sm1
                               WHERE    sm1.database_id = sm2.database_ID
                        FOR   XML PATH('') ,
                                  TYPE).value('.', 'varchar(max)'), 1, 1, '') AS MoveCmd
               FROM     sys.master_files sm2
  )

The CTE is now populated with the statement that has the MOVE switch.  We can now do another SELECT from sys.databases with an INNER JOIN to the CTE.

SELECT
'BACKUP DATABASE ' + name + ' TO DISK = ''' + @path + '' + name + '_COPY_ONLY_' + @date + '.bak'' WITH COMPRESSION, COPY_ONLY, STATS=5',
'RESTORE DATABASE '+ name + ' FROM DISK = ''' + @path + '' + name + '_COPY_ONLY_' + @date + '.bak'' WITH RECOVERY, REPLACE, STATS=5 ' + movecmdCTE.MoveCmd
FROM sys.databases d
INNER JOIN MoveCMDCTE ON d.name = movecmdcte.databasename
WHERE d.name LIKE '%DatabaseName%'

You can adjust the WHERE clause for just a single database or multiple.  Of course, you would want to adjust all of the UNC path statements for your particular environment.

You can download the entire script here.

Enjoy!

© 2018, John Morehouse. All rights reserved.

3 Replies to “Backup & Restore Script with a Move”

  1. This script was fantastic i am using from long time .
    Recently for big databases thought of using split backups. Could you please add split backup and restore script by including log backup/restore.

  2. I used the script but I am getting two empty rows even i got 8 databases in my instance I cannot able to figure out this I am executing this in SQL server 2019 RTM is this might be a issue could you please advice thanks

Hey you! Leave me a comment and start a discussion!

This site uses Akismet to reduce spam. Learn how your comment data is processed.