Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PowerShell-嵌套Try/Catch/Finally命令_Powershell_Powershell 2.0 - Fatal编程技术网

PowerShell-嵌套Try/Catch/Finally命令

PowerShell-嵌套Try/Catch/Finally命令,powershell,powershell-2.0,Powershell,Powershell 2.0,我试图编写一段代码,使用一些Invoke-Sqlcmd命令(由系统中的错误引起)在PowerShell中删除并重新创建MS SQL数据库。我想在这方面建立一些应急措施,以防在发出drop命令时目标机器上的另一个程序正在访问数据库。我认为这样做的一个好方法是将一个Try/Catch/Finally命令嵌套在另一个命令中,就像这样 $strDbName= database $strUsername= user $strPassword= pass $strmdfFilePath= "C:\foo.m

我试图编写一段代码,使用一些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将起作用。此简化代码证明了这一点(并将帮助您在任何窗口中进行测试):

B) 但这不是一个好的做法。您的错误处理代码(在catch/finally中)应该是健壮的、易于阅读的,并且不做复杂的事情。只需吐出错误消息以帮助调试,并可能关闭一些资源


然而,这是有争议的。。。检查此项。

您肯定可以嵌套它们。我想知道在你的情况下,你是否可以通过检查桌子的状态来避免它(我根本不知道怎么做)。那改变命令。。。为什么不首先将其设置为脱机呢?嗨,Matt,我确实研究过这个问题,通过查询数据库中打开的连接,这是可能的。我提出的方法显然不是做我想做的事情的最优雅的方式,因此我可能会研究在程序中实现一些防御性编码的过程;如果将变量设置为Microsoft.SqlServer.Management.Smo.Server,则可以使用“GetActiveDBConnectionsCount(“foobar”)”方法输出到特定数据库的当前连接数。@Fredulom将数据库设置为
脱机
状态可能会非常慢且占用大量资源。我认为更好的选择是使用
设置单用户
,断开其他所有人的连接,并回滚任何未提交的事务(=同样安全,但要快得多)。尽管如此,我仍然希望立即回滚。我希望这样做的原因是,我的意图是将此脚本提供给我们的支持分析师链,因此易于使用和自动化是我的优先事项。由于他们缺乏诊断SQL问题的经验,我希望代码能够尝试处理这一问题。我将研究上面Matt检查数据库中打开的连接的方法。我注意到在内部
catch
中设置
Break
,仍然执行final子句,而不是终止脚本。(我只测试了内部trycatcher没有完成的情况。)如果有任何trycatcher没有完成,是否要求每个trycatcher都有一个完成语句?(另外,我也同意嵌套的trycatch是一种糟糕的代码设计,因此我的问题是学术性的,而不是实用性的。)
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"
}