PowerShell - 嵌套 Try/Catch/Finally 命令
PowerShell - Nesting Try/Catch/Finally Commands
我正在尝试编写一段代码,使用一些 Invoke-Sqlcmd 命令(由我们系统中的错误引起)在 PowerShell 中删除并重新创建 MS SQL 数据库。我想为此建立一些应急措施,以防目标机器上的另一个程序在发出 drop 命令时访问数据库。我认为这样做的一个好方法是将一个 Try/Catch/Finally 命令嵌套在另一个命令中,就像这样;
$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;"
}
两个问题 - A) 嵌套 Try/Catch/Finally 命令真的有效吗?和 B) 这种类型的命令序列是好的做法吗?我没有测试机来尝试这个,如果有更简单的方法来执行这样的命令,我希望知道。
A) 嵌套 try/catch 可以工作。这个简化的代码证明了这一点(并将帮助您在任何 Windows 中进行测试):
Write-Host "0"
Try
{
Write-Host "1"
throw
}
Catch
{
Try
{
Write-Host "2"
throw
}
Catch
{
Write-Host "3"
}
Finally
{
Write-Host "4"
Exit
}
}
Finally
{
Write-Host "5"
}
B) 但这不是一个好的做法。您的错误处理代码(在 catch/finally 中)代码应该健壮、易于阅读并且不做复杂的事情。只需吐出错误消息以帮助调试并可能关闭一些资源。
但是,这是有争议的...检查这个 SO question。
我正在尝试编写一段代码,使用一些 Invoke-Sqlcmd 命令(由我们系统中的错误引起)在 PowerShell 中删除并重新创建 MS SQL 数据库。我想为此建立一些应急措施,以防目标机器上的另一个程序在发出 drop 命令时访问数据库。我认为这样做的一个好方法是将一个 Try/Catch/Finally 命令嵌套在另一个命令中,就像这样;
$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;"
}
两个问题 - A) 嵌套 Try/Catch/Finally 命令真的有效吗?和 B) 这种类型的命令序列是好的做法吗?我没有测试机来尝试这个,如果有更简单的方法来执行这样的命令,我希望知道。
A) 嵌套 try/catch 可以工作。这个简化的代码证明了这一点(并将帮助您在任何 Windows 中进行测试):
Write-Host "0"
Try
{
Write-Host "1"
throw
}
Catch
{
Try
{
Write-Host "2"
throw
}
Catch
{
Write-Host "3"
}
Finally
{
Write-Host "4"
Exit
}
}
Finally
{
Write-Host "5"
}
B) 但这不是一个好的做法。您的错误处理代码(在 catch/finally 中)代码应该健壮、易于阅读并且不做复杂的事情。只需吐出错误消息以帮助调试并可能关闭一些资源。
但是,这是有争议的...检查这个 SO question。