How To Automate SQL Server Database Restores
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.
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”.
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).
LinkedIn : www.linkedin.com/in/hema-sundar-m-9b2a0b57
How to automate SQL Server database restores
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.
set @counter = 1
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.
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
We now iterate our way through the rows within the temporary table, utilizing the cursor code
shown below:
BEGIN
select @RestoreString =
case
end
–select @RestoreString
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.
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
End
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
LinkedIn : www.linkedin.com/in/hema-sundar-m-9b2a0b57
How to automate SQL Server database restores
when @counter > 1 and @counter < @rows then
End
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
end
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:
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
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