Introduction
Sometimes, developers need to backup and restore databases. This is not a problem when you have SQL Server Management Studio installed. But what if Management Studio is not installed? In this case, you can use sqlcmd
utility. In some cases, you need to backup databases programmatically and this could be done via Server Management objects. In this article, I will shortly describe what SMO is and how to use it for database backup and restore.
Server Management Objects (SMO) is a collection of classes that represent the core SQL Server Database Engine objects. SMO allows you to programmatically manipulate SQL Server (2008, 2005, 2000 and 7.0). All functions available in SQL Server Management Studio are available in SMO but SMO includes several more features than Management Studio.
Background
Before writing any line of code, you must set the reference to the SMO assembly. In this article, you need add these components:
Microsoft.SqlServer.Smo
Microsoft.SqlServer.SmoExtended
Microsoft.SqlServer.Management.Sdk.Sfc
Microsoft.SqlServer.ConnectionInfo
When the references are added, you must add 2 using
statements for two namespaces:
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
Now you can start working with SMO. Before doing restore and backup tasks, you must connect to the server. This connection is provided by ServerConnection object
. It lets you connect to the server and assign that connection to the Server
object. The Server
object represents an instance of SQL Server. In SMO programming, the Server
object determines the connection to a physical SQL Server installation. When you are connected to the server, you can use 2 classes to perform backup and restore operations:
Microsoft.SqlServer.Management.Smo.Backup
Microsoft.SqlServer.Management.Smo.Restore
Using the Code
In this project, you can select whether you want to connect to the local instances of SQL Server or remote instances. In case you want to connect to the local instance, the fastest way to obtain a list of local instances is through registry.
The following code snippet shows you how to perform this:
RegistryKey rk = Registry.LocalMachine.OpenSubKey
(@"SOFTWARE\Microsoft\Microsoft SQL Server");
String[] instances = (String[])rk.GetValue("InstalledInstances");
if (instances.Length > 0)
{
foreach (String element in instances)
{
if (element == "MSSQLSERVER")
lstLocalInstances.Items.Add(System.Environment.MachineName);
else
lstLocalInstances.Items.Add(System.Environment.MachineName + @"\" + element);
}
}
For getting a list of remote instances, you have to use EnumAvailableSqlServers
method of SmoApplication
class. This method returns DataTable
with a few columns. In this case, we will use Name
column. This method has one parameter LocalOnly
of boolean data type. When this parameter is true
, then the method returns only local instances.
DataTable dt = SmoApplication.EnumAvailableSqlServers(false);
if (dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
AddNetworkInstance(dr["Name"].ToString());
}
}
This part of code populates lstNetworkInstances
with all instances of SQL Server asynchronously.
When instance is chosen, then you can connect to this instance by clicking on Connect button. After that, instance of ServerConnection
is created with specified serverInstance
property and authentication credentials. This project allows you to choose between 2 authentication modes (Windows authentication and SQL Server authentication). It's only up to you, which authentication mode you want to use. When you choose Windows Authentication, just check "Use Windows Authentication" checkbox. When you choose the second mode, then you must specify login and password.
When you are connected, a list of databases is got from Databases
property of Server
class. This property is a collection of Database
objects. You can easily loop through this collection and get name of every database in collection by reading Name
property.
Once you have selected server and database, you can perform backup operation. For backup operation, you must create instance of Backup
class and then assign the Action
property to BackupActionType.Database
. Now you have to add device you want to backup to. In many cases, it is file. You can backup not only to file, but you can backup to tape, logical drive, pipe and virtual device. You can also set Incremental
property indicating whether you want to perform incremental backup or not.
Backup bkp = new Backup();
this.Cursor = Cursors.WaitCursor;
this.dataGridView1.DataSource = string.Empty;
try
{
string fileName = this.txtFileName.Text;
string databaseName = this.ddlDatabase.SelectedItem.ToString();
bkp.Action = BackupActionType.Database;
bkp.Database = databaseName;
bkp.Devices.AddDevice(fileName, DeviceType.File);
bkp.Incremental = chkIncremental.Checked;
this.progressBar1.Value = 0;
this.progressBar1.Maximum = 100;
this.progressBar1.Value = 10;
bkp.PercentCompleteNotification = 10;
bkp.PercentComplete += new PercentCompleteEventHandler(ProgressEventHandler);
bkp.SqlBackup(srv);
MessageBox.Show("Database was successfully backed up to: " + fileName, "Info");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
this.Cursor = Cursors.Default;
this.progressBar1.Value = 0;
}
This example allows you to select backup file but be careful, this is not a local path. It is path within a selected instance.
SMO allows you to monitor progress of backup operation being performed. You can easily implement this feature. The first thing you must do is to create an event handler with PercentCompleteEventArgs
parameter. This parameter includes Percent
property which contains percent complete value. This value is an integer between 0
and 100
.
public void ProgressEventHandler(object sender, PercentCompleteEventArgs e)
{
this.progressBar1.Value = e.Percent;
}
Performing log backup operation is similar to database backup. Just set Action
property to Log
instead of Database
.
After you perform backup, it is good to verify that the backup was performed correctly and backup is not corrupted. You can easily do this by using SqlVerify
method of instance of Restore
class.
Restore rest = new Restore();
string fileName = this.txtFileName.Text;
this.Cursor = Cursors.WaitCursor;
this.dataGridView1.DataSource = string.Empty;
try
{
rest.Devices.AddDevice(fileName, DeviceType.File);
bool verifySuccessful = rest.SqlVerify(srv);
if (verifySuccessful)
{
MessageBox.Show("Backup Verified!", "Info");
DataTable dt = rest.ReadFileList(srv);
this.dataGridView1.DataSource = dt;
}
else
{
MessageBox.Show("ERROR: Backup not verified!", "Error");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
this.Cursor = Cursors.Default;
}
Let’s consider you have your database successfully backed up. It would be great to restore database from this backup. SMO allows you to do this very easily. Database restore operation is performed by Restore
class which is in Microsoft.SqlServer.Management.Smo.Restore
namespace. Before running any restore, you must provide database name and valid backup file. Then you must set Action
property. In case you want to restore database, set it to RestoreActionType.Database
. In case you want to restore Log
, just set it to RestoreActionType.Log
. During restore, you can monitor progress of restoring operation. This could be done the same way as in case of database backup.
Restore res = new Restore();
this.Cursor = Cursors.WaitCursor;
this.dataGridView1.DataSource = string.Empty;
try
{
string fileName = this.txtFileName.Text;
string databaseName = this.ddlDatabase.SelectedItem.ToString();
res.Database = databaseName;
res.Action = RestoreActionType.Database;
res.Devices.AddDevice(fileName, DeviceType.File);
this.progressBar1.Value = 0;
this.progressBar1.Maximum = 100;
this.progressBar1.Value = 10;
res.PercentCompleteNotification = 10;
res.ReplaceDatabase = true;
res.PercentComplete += new PercentCompleteEventHandler(ProgressEventHandler);
res.SqlRestore(srv);
MessageBox.Show("Restore of " + databaseName +
" Complete!", "Restore",MessageBoxButtons.OK,MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
this.Cursor = Cursors.Default;
this.progressBar1.Value = 0;
}
Conclusion
In this article, I have described how to use SMO to perform database backup and restore operations. Abilities of SMO are not limited to these 2 types of operations. SMO provides a lot of features to interact with SQL Server.
History
- 31 Oct 2010 - Original version posted