views:

870

answers:

4

What is a quick example / demo of an msbuild task to delete then restore a database and also maybe run any .sql files against the restored database?

+1  A: 

Use the ExecTask and call sqlcmd.exe or a cmd script to do what ever you want to with your database.

Louis Haußknecht
+1  A: 

We use ExecTask and powershell script. Relevant Powershell code is here:

$Server = new-object ("Microsoft.SqlServer.Management.Smo.Server") $ServerName
$Database = new-object ("Microsoft.SqlServer.Management.Smo.Database") ($Server, $DatabaseName)

function RestoreDb([string] $BackupFile =  $(throw "Backup file required."))
{

  write-host "Taking db offline"
  $Database.SetOffline()
  $restore = new-object ('Microsoft.SqlServer.Management.Smo.Restore')


  $fil=new-object "Microsoft.SqlServer.Management.Smo.BackupDeviceItem"
  $fil.DeviceType='File'
  $fil.Name= $BackupFile
  $restore.Action="Database"
  $restore.Devices.Add($fil)
  $restore.Database=$DatabaseName
  $restore.ReplaceDatabase = $true
  $restore.Restart  = $true
  write-host "Restoring database $DatabaseName  on  $ServerName from file $BackupFile"
  $restore.SqlRestore($Server)
  write-host "Taking db online"
  $Database.SetOnline()
}

And relevant MSBuild

<Exec WorkingDirectory="$(BuildRoot)"   Command="powershell -command  .\run_migration.ps1"/>
bh213
A: 

Here's the outline of an msbuild task I wrote to do that:

    public class RestoreDb : Task
    {
        #region RequiredParameters
        [Required]
        public string ServerName
        {
            get
            {
                return m_ServerName;
            }
            set
            ...
        }
        [Required]
        public string DbName
        ...
        public string BackupFileName
        ...
        #endregion
        public override bool Execute()
        {
            try
            {
                SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder();
                connectionStringBuilder.IntegratedSecurity = true;
                connectionStringBuilder.DataSource = ServerName;
                SqlConnection connection = new SqlConnection(connectionStringBuilder.ToString());
                connection.Open();

                Server server = new Server(new ServerConnection(connection));

                if (server.Databases[DbName] != null)
                {
                    Log.LogMessage("Dropping existing " + DbName + " on " + ServerName);
                    server.Databases[DbName].Drop();
                }
                else
                {
                    Log.LogMessage(DbName + " on " + ServerName + " doesn't exist.");
                }

                Log.LogMessage(MessageImportance.High, "Restoring " + DbName + " on " + ServerName);
                Database newDb = new Database(server, DbName);

                Restore rs = new Restore();
                rs.NoRecovery = false;
                FileInfo fi = new FileInfo(server.Settings.BackupDirectory + "\\" + BackupFileName);
                BackupDeviceItem bdi = new BackupDeviceItem(fi.FullName, DeviceType.File);
                rs.Devices.Add(bdi);
                rs.Database = DbName;
                rs.Action = RestoreActionType.Database;

                rs.SqlRestore(server);
                Log.LogMessage(MessageImportance.High, "Restoring done.");
            }
            catch( Exception exc)
            {
                Log.LogErrorFromException(exc);
            }
            return !Log.HasLoggedErrors;
        }
        private string m_DbName;
        ...
    }
}

use as:

<UsingTask AssemblyFile="bin\Release\MyTask.dll" TaskName="RestoreDb" />
    <RestoreDb ServerName="localhost\sql2005" DbName="myDb" BackupFileName="myDb.bak"/>

Any and all comments welcome!

Jan

jan
+1  A: 

I use the MSBuild extension pack MSBuild extension pack to modify configuration files, create application pools, and even send emails.

Rihan Meij