SSIS 数据流脚本任务错误处理

Posted

技术标签:

【中文标题】SSIS 数据流脚本任务错误处理【英文标题】:SSIS Dataflow script task error handling 【发布时间】:2010-12-02 04:55:23 【问题描述】:

我有一个在 SSIS 数据流中间执行转换的脚本任务。如果脚本失败(比如说它试图将 alpha 转换为数字),我需要它以“失败”状态停止并返回到主包,然后利用数据流任务事件处理程序 OnError 正常退出.

目前我发现数据流中的脚本任务返回一个 .net 错误弹出窗口,然后我必须清除它。我在代码周围尝试了一个 Try Catch,这似乎停止了调试窗口的出现,但我似乎无法让它以“失败状态”退出脚本,这将导致包失败。 Dts.TaskResult = Dts.Results.Failure 在数据流任务中似乎无效。目前我正在尝试这个:

    Catch e As System.Exception
        Me.ComponentMetaData.FireError(-1, "", "Error: ", e.Message, 1, True)
        While Not e.InnerException Is Nothing
            e = e.InnerException
            Me.ComponentMetaData.FireError(-1, "", "InnerException: ", e.Message, 1, True)
        End While
        Exit Sub
    End Try

...但这所做的只是跳过坏行。数据流继续。问题是让它以“失败”退出,因此会触发包中的 onError 错误处理程序事件。

任何建议都非常感谢。 格伦

【问题讨论】:

顺便说一句,如果它在数据流中,那么它是一个脚本组件,而不是一个脚本任务。 【参考方案1】:

脚本转换没有返回成功或失败的相同功能。您可以使用以下代码强制出错:

    If Row.TestColumn = "Value I Want To Error On" Then
        Error (1)
    End If

基本上,Error 对象(函数?方法?随便!)将允许您模拟错误。意思是,您可以使用此代码使包错误。

【讨论】:

谢谢。作为后续行动,我意识到我的最后出现了一些混乱。弹出错误实际上是可取的,并且可能需要前端知道问题所在。我放弃了脚本中的所有 Try Catch 代码,让包自行失败,当我在前端运行它时,VS 中的调试窗口被替换为 Web 错误(没关系),在后端,包继续OnError 事件(清理一些表)。由于需要在 VS 中单击“确定”来清除错误,因此出现了困惑,但是当您在 VS 之外运行包时,这当然不是必需的。 您说得对,删除 Try Catch 块将允许失败自动失败。大约1个月前我遇到了这个问题并得出了相同的结论。我首先通过在 Try Catch 块中强制出错来找到解决方案。然后我在 Catch 块中添加了一个错误。一旦我得到这个来强制失败,我意识到问题完全是 Try Catch 块。让 SSIS 处理异常,而不是自己处理。【参考方案2】:

我一直在寻找这个问题的答案。弹出错误对我来说太烦人了!为了避免这种情况,一个“简单”的解决方案(hack)是这样的:

与其在 .FireError 之后抛出错误,不如在脚本转换中创建一个新的 DT_UI1 输出列,例如“ValidationColumn”,并将其设置为 1 或 0(不是布尔值,原因将变得清楚)。

紧跟在脚本组件之后,添加派生列转换,并将 ValidationColumn 替换为公式:1/ValidationColumn。 (这不适用于布尔值)。当然,这会产生除以零错误,并且(使用默认设置)使派生列转换失败,从而立即导致数据流组件失败。瞧!

错误日志包含来自 .FireError 的原始验证失败消息,紧随其后的是除以零错误。

这可能是一个 hack,但在有人想出更好的主意之前...

顺便说一句,我正在使用它来检查 Excel 文件是否在正确的位置(或替代位置)具有正确的标题,同时使用 IMEX=1,以便使用单个数据加载 2 个或更多不同的列变体流...

【讨论】:

【参考方案3】:

回想起来,除以零错误是没有必要的。

在我当前的解决方案中,我正在捕获错误,然后执行 FireError,然后重新实现异常处理,如下所示:

If excludeHeader = -1 Then
    'Throw New InvalidDataException("Invalid exclude column: " & Variables.excludeColumn)
    ComponentMetaData.FireError(0, ComponentMetaData.Name.Trim(), "Invalid exclude column: " & Variables.excludeColumn, String.Empty, 0, True)
    excelConnection.Close()
    excelConnection.Dispose()
    Return
End If

之所以有效,是因为它包含在源脚本中,并且如果数据流设置为在出现 1 个错误后失败,它也可以在转换脚本中工作。如果没有,脚本将需要实现一个错误输出路径,坦率地说,我没有时间......

【讨论】:

【参考方案4】:

以下是我在循环中创建的脚本任务。这不是您问题的直接答案,但总体思路会有所帮助。

脚本任务保存在序列容器中。并且序列容器的variable名为Propagate被设置为false。此外,对于sequence containerMaximumErrorCount 属性设置为零。因此,当序列容器内发生错误时,它会以红色显示,触发 OnError 事件——但循环继续。为此,为序列容器创建一个 onerror 事件处理程序非常重要。

在脚本任务内部,它在catch 块内被强制失败(通过将任务结果设置为失败)。此外,异常消息存储在一个变量中,用于将其存储到错误记录表中。此错误数据插入发生在 OnError 事件处理程序(如上所述)的执行 sql 任务中。

参考:MSDN - ScriptObjectModel.TaskResult Property

使用Script任务代码中Dts对象的TaskResult属性通知包Script任务成功或失败。

脚本任务中的 catch 块如下所示。

  Catch ex As Exception

        Dim exceptionVariable As Microsoft.SqlServer.Dts.Runtime.Variables = Nothing
        Dts.VariableDispenser.LockOneForWrite("User::ScriptException", exceptionVariable)
        exceptionVariable("User::CustomScriptException").Value = ex.Message
        exceptionVariable.Unlock()
        Dts.Events.FireError(-1, "Task Name", ex.Message, [String].Empty, 0)
        Dts.TaskResult = Dts.Results.Failure
  End Try

控制流

【讨论】:

以上是关于SSIS 数据流脚本任务错误处理的主要内容,如果未能解决你的问题,请参考以下文章

SSIS 脚本任务引发死锁错误

SSIS 脚本任务引发的错误

SSIS 执行 Analysis Services 任务错误:指定的登录会话不存在。它可能已经被终止

部署时SSIS任务脚本损坏

SSIS 包中的 C# 脚本在 SQL Server 表的数据执行过程中挂起,没有明确的错误消息

无法使用脚本任务从 SSIS 发送邮件 - 超时