Powershell Invoke-Sqlcmd的错误检测并不总是有效?

时间:2014-05-05 11:42:31

标签: sql powershell error-handling

通过执行位于文件夹中的查询列表来更新数据库。

我需要能够检测任何错误,这些错误也会导致SQL Server Management Studio中的“Query completed with errors”。

以下用于检测“无效对象”错误:

PS SQLSERVER:\> $ErrorActionPreference
Stop
PS SQLSERVER:\> $Error.Clear()
PS SQLSERVER:\> $Error
PS SQLSERVER:\> Invoke-Sqlcmd -ServerInstance .\SQLEXPRESS -Database Test -Query "select * from doesnotexist" -ErrorAction SilentlyContinue
PS SQLSERVER:\> $Error.Exception
Invalid object name 'doesnotexist'.
PS SQLSERVER:\>

对选择1/0执行相同操作工作:

PS SQLSERVER:\> $ErrorActionPreference
Stop
PS SQLSERVER:\> $Error.Clear()
PS SQLSERVER:\> $Error
PS SQLSERVER:\> Invoke-Sqlcmd -ServerInstance .\SQLEXPRESS -Database Test -Query "select 1/0" -ErrorAction SilentlyContinue
PS SQLSERVER:\> $Error.Exception
PS SQLSERVER:\>

我希望这会导致“遇到零除错误”错误,就像在SSMS中一样。

未检测到此特定错误让我想知道其他错误是否也会被检测不到。

知道为什么会发生这种情况以及如何确保检测到所有错误?

更新

事实证明我在安装的服务器上没有可用的Invoke-Sqlcmd,所以第二次认为我必须使用sqlcmd.exe。

我认为这对我有用:

$tempfile = [io.path]::GetTempFileName()
$cmd = [string]::Format("sqlcmd -S {0} -U {1} -P {2} -d {3} -i {4} -b > $tempfile",
    $g_connectionstring."Data Source",
    $g_connectionstring."User ID",
    $g_connectionstring."Password",
    $g_connectionstring."Initial Catalog",
    $path)
Invoke-Expression -Command $cmd
if ($LASTEXITCODE)
{
    $err = Get-Content $tempfile | Out-String
    Corax-Message "SQL" "Error" $err
    exit
}
Remove-Item $tempfile

3 个答案:

答案 0 :(得分:7)

无论ErrorAction设置如何,invoke-sqlcmd cmdlet都会在SQL Server 2008,2008和2012版本的cmdlet中出现错误,其中除以0之类的T-SQL错误不会导致错误。我在此处记录了一个连接项,您可以在此处查看详细信息:

https://connect.microsoft.com/SQLServer/feedback/details/779320/invoke-sqlcmd-does-not-return-t-sql-errors

注意:此问题已在SQL 2014中修复,但似乎未出现或将要为以前的版本提供修复。

答案 1 :(得分:4)

您使用-ErrorAction SilentlyContinue忽略错误,将其更改为-ErrorAction Stop

修改

如果您想要错误处理,请不要使用Invoke-SqlCmdhttp://blogs.technet.com/b/heyscriptingguy/archive/2013/05/06/10-tips-for-the-sql-server-powershell-scripter.aspx

您可以使用此答案中的GenericSqlQuery功能:Powershell SQL SELECT output to variable 这会错误地抛出错误。

答案 2 :(得分:2)

正如拉夫的另一个答案中已经提到的那样;未检测到错误的主要原因是-ErrorAction SilentlyContinue(因为您绕过了错误)。如果你甚至完全省略了这个选项;你会看到预期的错误

Invoke-Sqlcmd -ServerInstance .\SQLEXPRESS -Database Test -Query "select 1/0"

您也可以使用其他错误选项,例如

  

停止运行错误-AbortOnError

     

显示错误-OutputSqlErrors

在相关的MSDN文档中都提到了这一点。看看Invoke-Sqlcmd cmdlet