0% found this document useful (0 votes)
1 views11 pages

How To Automate SQL Server Database Restores

The document outlines a process for automating SQL Server database restores, specifically for the 'SQLShackFinancial' database, to be executed nightly at 3:00 AM. It details the steps to delete the previous day's database, download the latest backup, and restore it using SQL Server Management Studio, including the use of temporary tables and cursors to manage file properties. The final execution of the restore command is achieved through dynamic SQL, ensuring the database is restored correctly to the specified directory.

Uploaded by

govindarao dba
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views11 pages

How To Automate SQL Server Database Restores

The document outlines a process for automating SQL Server database restores, specifically for the 'SQLShackFinancial' database, to be executed nightly at 3:00 AM. It details the steps to delete the previous day's database, download the latest backup, and restore it using SQL Server Management Studio, including the use of temporary tables and cursors to manage file properties. The final execution of the restore command is achieved through dynamic SQL, ensuring the database is restored correctly to the specified directory.

Uploaded by

govindarao dba
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

How to automate SQL Server database restores

Introduction
A few days back I encountered an interesting challenge. The client wanted to have copies of the
nightly backups of the transactional databases restored on a warehouse server, to be utilized to
update the warehouse.

The over all process

Prior to the pushing the daily backup to the warehouse server, the previous days restore is deleted.
The important point being that the “SQLShackFinancial” database is no longer present on the
warehouse server. Having been deleted, downloading of the backup file begins and the restore of the
current backup version begins. Normal warehouse processing then ensues and so the cycle
continues.

The interesting part of the challenge was to automate the restore process and to have the SQL Server
Agent run the job each morning at 3:00 AM. This is what we shall be looking at in today’s “get
together”.

Let’s get started.

Getting Started

To begin, we require a bit of knowledge of the backup that we have been charged to restore. In our
case, it is the “SQLShackFinancial.bak” backup and the backup has been placed at the following
location.

We begin by opening SQL Server Management Studio and opening a new query.

LinkedIn : www.linkedin.com/in/hema-sundar-m-9b2a0b57
How to automate SQL Server database restores

We create a small temporary table which will hold the incoming backup’s properties and respective
values, thus insuring that the restored database is exactly similar to the copy on the production
server. We also create a variable called @path which will contain the path to the backup (see below).

I have taken the liberty of hardwiring this path to make it easier to grasp, however in a real
production environment, this would be set by an environmental variable or the like.

LinkedIn : www.linkedin.com/in/hema-sundar-m-9b2a0b57
How to automate SQL Server database restores

As a “sanity check”, in SQL Server Management Studio and PRIOR to pushing the latest backup down
to our server, we bring up the database properties window for the “SQLShackFinancial” database.
We note that there is one primary file with two secondary files and finally the log file (see above).
We now delete the database as the most current version of the database will be restored from the
current backup.

Meanwhile back in the query that we are constructing, we can execute the code that we have thus
far and see the contents of the backup file (see below).

We note that the statistics are fairly similar.

The one important point to note is that the

LinkedIn : www.linkedin.com/in/hema-sundar-m-9b2a0b57
How to automate SQL Server database restores

EXEC (‘restore filelistonly from disk = ''' + @path + '''')

command first lists the primary data file, then the secondary data files and lastly the log file is listed.

It is this premise that we base the rest of this exercise upon, and the reasons for which we shall see
in due course.

We now declare a few variables and count the number of rows in #tmp. This is a critical activity as we
wish to track the rows one by one, as we iterate through the rows in the temporary table. Note that
@counter is set to 1.

Declare @RestoreString as Varchar(max)

Declare @NRestoreString as NVarchar(max)

DECLARE @LogicalName as varchar(75)

Declare @counter as int

Declare @rows as int

set @counter = 1

select @rows = COUNT(*) from #tmp

As we note in the screen dump above, that we have four rows.

LinkedIn : www.linkedin.com/in/hema-sundar-m-9b2a0b57
How to automate SQL Server database restores
At this point in time, we are going to become “SQL Server Outlaws” and real naughty folks as we are
going to do a “no-no” and utilize a cursor. As the source data comes from a temporary table, we shall
not lock up any physical tables. I therefore have no qualms in utilizing the cursor.

We continue by declaring our cursor (see above highlighted in blue).

Opening the cursor, we set our @RestoreString variable as follows:

set @RestoreString =

LinkedIn : www.linkedin.com/in/hema-sundar-m-9b2a0b57
How to automate SQL Server database restores
'RESTORE DATABASE [SQLShackFinancial] FROM DISK = N''C:\SQL

Shack\SQLShackFinancial.bak''' + ' with '

We now iterate our way through the rows within the temporary table, utilizing the cursor code
shown below:

Fetch NEXT FROM MY_Cursor INTO @LogicalName

While (@@FETCH_STATUS <> –1)

BEGIN

IF (@@FETCH_STATUS <> –2)

select @RestoreString =

case

when @counter = 1 then

@RestoreString + 'move N''' + @LogicalName + '''' + ' TO N''C:\SQL Server Data\'+

@LogicalName + '.mdf' + '''' + ', '

when @counter > 1 and @counter < @rows then

@RestoreString + 'move N''' + @LogicalName + '''' + ' TO N''C:\SQL Server Data\'+

@LogicalName + '.ndf' + '''' + ', '

WHen @LogicalName like '%log%' then

@RestoreString + 'move N''' + @LogicalName + '''' + ' TO N''C:\SQL Server Data\'+

@LogicalName + '.ldf' +''''

end

–select @RestoreString

set @counter = @counter + 1

FETCH NEXT FROM MY_CURSOR INTO @LogicalName

END

This code requires some explanation. While there are still rows to be read within the temporary table
we shall continue with the outer “while loop”. When there are records to be read, the value of
@@FETCH_STATUS will be 0. After the last record is read, @@FETCH_STATUS returns -1 which will
cause the code to break out of the loop. As long as there are no missing records, the

LinkedIn : www.linkedin.com/in/hema-sundar-m-9b2a0b57
How to automate SQL Server database restores
@@FETCH_STATUS should never be -2 thus the second loop is a “safety valve” and is totally
dependent upon the outer loop.

Details of the return codes may be found at the following URL:

https://msdn.microsoft.com/en-us/library/ms187308.aspx

Above I had mentioned that routinely the way that the physical files are rendered when utilizing the
“restore file list only” command are that the first file pulled is the primary data file, then come the
secondary files and last the log file. The fact that this is so makes our task all the easier.

Looking at the code snippet below (extracted from the code above), when the counter is “1” then we
create the physical primary file name from the logical file name plus the hardwired path and give the
file name an extension of “mdf”. All of this is concatenated to @ReportString (see code in green
below).

case

when @counter = 1 then

@RestoreString + 'move N''' + @LogicalName + '''' + ' TO N''C:\SQL Server Data\'+

@LogicalName + '.mdf' + '''' + ', '

when @counter > 1 and @counter < @rows then

@RestoreString + 'move N''' + @LogicalName + '''' + ' TO N''C:\SQL Server Data\'+

@LogicalName + '.ndf' + '''' + ', '

WHen @LogicalName like '%log%' then

@RestoreString + 'move N' + @LogicalName + '''' + ' TO N''C:\SQL Server Data\'+

@LogicalName + '.ldf' +''''

End

set @counter = @counter + 1

When the value of @counter is greater than one BUT less than the total count of rows then we
KNOW that we are dealing with secondary data files and perform the same naming process however
this time the file name extension will be “.ndf” (see the code in purple below):

case

when @counter = 1 then

@RestoreString + 'move N''' + @LogicalName + '''' + ' TO N''C:\SQL Server Data\'+

@LogicalName + '.mdf' + '''' + ', '

LinkedIn : www.linkedin.com/in/hema-sundar-m-9b2a0b57
How to automate SQL Server database restores
when @counter > 1 and @counter < @rows then

@RestoreString + 'move N''' + @LogicalName + '''' + ' TO N''C:\SQL Server Data\'+

@LogicalName + '.ndf' + '''' + ', '

WHen @LogicalName like '%log%' then

@RestoreString + 'move N''' + @LogicalName + '''' + ' TO N''C:\SQL Server Data\'+

@LogicalName + '.ldf' +''''

End

set @counter = @counter + 1

When the value of @counter is equal to the total count of rows then we KNOW that we are dealing
the log file see the code in brown below:

case

when @counter = 1 then

@RestoreString + 'move N''' + @LogicalName + '''' + ' TO N''C:\SQL Server Data\'+

@LogicalName + '.mdf' + '''' + ', '

when @counter > 1 and @counter < @rows then

@RestoreString + 'move N''' + @LogicalName + '''' + ' TO N''C:\SQL Server Data\'+

@LogicalName + '.ndf' + '''' + ', '

WHen @LogicalName like '%log%' then

@RestoreString + 'move N''' + @LogicalName + '''' + ' TO N''C:\SQL Server Data\'+

@LogicalName + '.ldf' +''''

end

set @counter = @counter + 1

FETCH NEXT FROM MY_CURSOR INTO @LogicalName

The astute reader will note that regardless of which option, the “case” turns out to be, @counter is
incremented by 1 (with each pass) and the next row is retrieved from the cursor.

LinkedIn : www.linkedin.com/in/hema-sundar-m-9b2a0b57
How to automate SQL Server database restores

Running what we have thus far, we can see the string that we have created by concatenating all the
file names (see above).
Our final task is to execute the string and close and de-allocate the cursor. The code that achieves
this may be seen below:

set @NRestoreString = @RestoreString

EXEC sp_executesql @NRestoreString

CLOSE MY_CURSOR

DEALLOCATE MY_CURSOR

We set the value of @NRestoreString to the value of @RestoreString.

“ sp_executesql “ requires the string to be in NVARCHAR() format.


The reader will remember that @NRestoreString is NVARCHAR(max). We could have utilized
@NRestoreString right from the outset.

Utilizing sp_executesql we now execute @NRestoreString. The results of the execution may be seen
below.

LinkedIn : www.linkedin.com/in/hema-sundar-m-9b2a0b57
How to automate SQL Server database restores

We note that SQLShackFinancial has been restored (see below and to the left).

Looking at the location of the physical files, we find that the data files were actually restored to
where we had requested (see below).

LinkedIn : www.linkedin.com/in/hema-sundar-m-9b2a0b57
How to automate SQL Server database restores

It should be noted at this point that I deliberately restored the database to the directory “SQL Server
Data” for this exercise. Normally these files are located in the proper SQL Server 11 Data Directory.

Looking our “SQL Server Data” directory, we note our four files.

LinkedIn : www.linkedin.com/in/hema-sundar-m-9b2a0b57

You might also like