2015-09-11 5 views
4

Я пытаюсь написать фрагмент кода для удаления и воссоздания базы данных MS SQL в PowerShell с использованием некоторых команд Invoke-Sqlcmd (вызванных ошибкой в ​​наших системах). Я хотел бы создать некоторые непредвиденные обстоятельства в этом случае, если другая программа на целевой машине будет обращаться к базе данных в момент выдачи команды drop. Я думал, что хороший способ сделать это будет путем вложения одной команды Try/Catch/Finally внутри другого, например;PowerShell - команды вложения/вставки/вложения

$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 на самом деле? и В) Является ли этот тип последовательности команд хорошей практикой? У меня нет тестовой машины, чтобы попробовать это, и если бы был более простой способ выполнить такую ​​команду, я бы предпочел знать.

+1

Возможно, вы можете их разложить. Я бы задался вопросом в вашем случае, если вы можете избежать этого, проверив состояние таблицы перед рукой (я не знаю, как это сделать вообще). Это изменить команду ... Почему бы просто не отключить ее в первую очередь? – Matt

+0

Привет, Мэтт, я просмотрел это, и это возможно, запросив базу данных для Open Connections. Метод, который я предложил, определенно не кажется самым изящным способом делать то, что я хочу, поэтому я могу исследовать этот ход реализации какой-либо защитной кодировки в процессе. – Fredulom

+0

Чтобы следить за этим, я нашел следующую информацию; если вы установите переменную как Microsoft.SqlServer.Management.Smo.Server, вы можете использовать метод GetActiveDBConnectionsCount («foobar») для вывода текущего количества подключений к конкретной базе данных. – Fredulom

ответ

4

A) Вложенные попытки/улов будут работать. Этот упрощенный код доказывает это (и поможет вам проверить в любой 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.

+0

Причина, по которой я хочу сделать это, заключается в том, что я намерен подавать этот скрипт по нашей цепочке аналитиков поддержки, поэтому мой приоритет был простота использования и автоматизации. Из-за отсутствия опыта в диагностике проблем SQL я хотел, чтобы код попытался справиться с этим. Я рассмотрю метод Мэтта выше для проверки Open Connections в базе данных. – Fredulom