I've been searching for a long time and this is my first StackOverFlow question so I hope that there is no published answer out there that I should have found!
SQL server .bak files can contain multiple databases. I need to programmatically restore each database within the file.
All the examples I have found use .bak files with one database. For example:
http://www.sqlmusings.com/2009/06/01/how-to-restore-sql-server-databases-using-smo-and-powershell/
I'm using powershell but that's not relevant:
$restore = new-object("Microsoft.SqlServer.Management.Smo.Restore")
$restore.NoRecovery = $false;
$restore.ReplaceDatabase = $true;
$restore.Action = "Database"
$backup_device = New-Object("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($bak_file_full_path, "File")
$restore.Devices.Add($backup_device)
$datatable_header = $restore.ReadBackupHeader($sql_server);
The $datatable_header contains information about eack underlying database stored in the bak file.
foreach($backup_row in $datatable_header.Rows)
{
$backup_name = $backup_row["BackupName"];
$database_name = $backup_row["DatabaseName"];
$backup_description = $backup_row["BackupName"];
$backup_position = $backup_row["Position"];
$restore_as_name = $restore_as;
if ( ! [string]::IsNullOrEmpty($backup_name) )
{
$restore_as_name += "_" + $backup_name;
}
$restore_as_name = $restore_as_name.ToLower();
Write-Host "Restore $restore_as_name";
$restore_file_data = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
$restore_file_data.LogicalFileName = $database_name;
$restore_file_data.PhysicalFileName = $data_path + $restore_as_name + "_data.mdf"
$restore_file_log = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
$restore_file_log.LogicalFileName = $database_name + "_Log";
$restore_file_log.PhysicalFileName = $data_path + $restore_as_name + "_log.ldf"
#the logical file names should be the logical filename stored in the backup media
$restore.Database = $database_name;
$restore.RelocateFiles.Add($restore_file_data)
$restore.RelocateFiles.Add($restore_file_log)
$restore.SqlRestore($sql_server)
$restore.RelocateFiles.Clear();
#BackupName, BackupDescription, BackupType, ExpirationDate, Compressed, Position
}
The missing part is the use of the "Position" which is a number which identifies the db in the file ref:
https://msdn.microsoft.com/en-us/library/ms178536.aspx
If you were doing this in T-SQL some sudo code would be:
RESTORE DATABASE [%DBNEW%] FROM DISK = `[%PATHBACKUP%]` WITH FILE = [%POSITION%]
So, does anyone know how to use SQL management objects and the position / file attribute?