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 container
,MaximumErrorCount
属性设置为零。因此,当序列容器内发生错误时,它会以红色显示,触发 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 执行 Analysis Services 任务错误:指定的登录会话不存在。它可能已经被终止