I'm trying to write a piece of code to drop and re-create an MS SQL Database in PowerShell using some Invoke-Sqlcmd commands (caused by an error in our systems). I wanted to build some contingency into this in case another program on the target machine is accessing the Database at the time that the drop command is issued. I thought that a good way to do this would be by nesting one Try/Catch/Finally command inside another, like so;
$strDbName= database
$strUsername= user
$strPassword= pass
$strmdfFilePath= "C:\foo.mdf"
$strldfFilePath= "C:\bar.ldf"
Try
{
Write-Host "INFO: Attempting Database DROP command..."
Invoke-SqlCmd -Username "$strUserName" -Password "$strPassword" -Query "DROP database [$strDbName];"
}
Catch
{
Try
{
Invoke-SqlCmd -Username "$strUserName" -Password "$strPassword" -Query "ALTER database [$strDbName] set offline with ROLLBACK IMMEDIATE;"
Invoke-SqlCmd -Username "$strUserName" -Password "$strPassword" -Query "DROP database [$strDbName];"
}
Catch
{
Write-Host "Error message"
}
Finally
{
Exit
}
}
Finally
{
Invoke-SqlCmd -Username "$strUserName" -Password "$strPassword" -Query "CREATE DATABASE [$strDbName] ON (FILENAME = '$dirMdfFilePath'),(FILENAME = '$dirLdfFilePath') for ATTACH;"
}
Two questions - A) Does nesting Try/Catch/Finally commands actually work? and B) Is this type of command sequence good practice? I don't have a test machine to try this out on and if there was an easier way to perform such a command I would prefer to know.
offline
state can be fairly slow and resource intensive. I think a better bet would be to useset single_user
, disconnecting everyone else and rolling back any uncomitted transaction (= just as safe, but much faster). Still with immediate rollback though – Mythology