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

4
我有一个脚本任务,它在SSIS数据流中执行转换。如果脚本失败(例如,尝试将字母转换为数字),我需要它停止并返回到主包,并利用数据流任务事件处理程序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
顺便说一下,如果它在数据流中,那么它是一个脚本组件,而不是脚本任务。 - John Saunders
4个回答

3

脚本转换不具备相同的成功或失败返回功能。您可以使用以下代码强制发生错误:

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

基本上,Error对象(函数?方法?随便怎么说!)可以让您模拟错误。也就是说,您可以通过此代码使程序包出现错误。


谢谢。作为后续,我意识到我这边存在一些混淆。弹出式错误实际上是可取的,也可能是前端了解问题所在的必要条件。我放弃了脚本中所有的Try Catch代码,并让包自行失败,当我在前端运行它时,VS中的调试窗口被替换为Web错误(这是可以接受的),而在后端,包继续执行OnError事件(清理一些表)。混淆来自于需要在VS中单击“确定”以清除错误,但当您在VS外运行包时,这当然不是必需的。 - Glenn M
你说得对,移除Try Catch块将允许失败自动失败。我大约一个月前遇到了这个问题,并得出了同样的结论。我首先通过在Try Catch块中强制引发错误来找到解决方案。然后我在Catch块中添加了一个错误。当我成功地强制引发了失败时,我意识到问题在于整个Try Catch块。让SSIS处理异常而不是自己处理它。 - Registered User

1

回顾过去,除以零的错误是不必要的。

在我的当前解决方案中,我正在捕获错误,然后执行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个错误后停止。如果没有,脚本就需要实现一个错误输出路径,但老实说,我没有时间做...

1
我已经搜索了一段时间来寻找这个问题的答案。弹出式错误对我来说太烦人了!为了避免这种情况,一个“简单”的解决方案(黑客)是这样的:
在.FireError之后,不要抛出错误,而是在脚本转换中创建一个新的DT_UI1输出列,例如“ValidationColumn”,并将其设置为1或0(由于很快就会明白的原因,不使用布尔值)。
在脚本组件之后立即添加一个派生列转换,并用公式1/ValidationColumn替换ValidationColumn。(这不能与布尔值一起使用)。当然,这会生成一个除以零的错误,并且(使用默认设置)使派生列转换失败,从而立即使数据流组件失败。大功告成!
错误日志具有来自.FireError的原始验证失败消息,紧随其后的是除以零错误。
这可能是一个黑客,但在有人想出更好的主意之前...
顺便说一句,我正在使用它来检查Excel文件是否具有正确的标题以及正确的位置(或备选位置),并与使用IMEX=1一起使用,以便使用单个数据流加载2个或更多不同的列变化...

0
以下是我在循环内创建的脚本任务。这并不是你问题的直接答案,但整体思路有所帮助。
将脚本任务保留在序列容器中。并且序列容器中的variable命名为Propagate设置为false。此外,对于sequence container,MaximumErrorCount属性设置为零。因此,在序列容器中发生错误时,它会显示为红色,OnError事件触发 - 但循环仍在继续。为使其正常工作,必须为序列容器创建onerror事件处理程序。
在脚本任务内部,它通过在catch块中强制失败(将任务结果设置为Failure)来失败。同时,异常消息存储在一个变量中,以便将其存储到错误日志表中。此错误数据插入从OnError事件处理程序的执行SQL任务中发生。
参考:MSDN - ScriptObjectModel.TaskResult Property
在脚本任务代码中使用Dts对象的TaskResult属性来通知包脚本任务的成功或失败。
脚本任务内部的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

控制流程

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接