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

发布于 2024-08-06 06:08:17 字数 740 浏览 7 评论 0原文

我有一个脚本任务在 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 错误处理程序事件。

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

I have a script task that is performing transformations in the middle of a SSIS dataflow. If the script fails (say it tries to convert alpha to numeric) I need it to stop with a 'failed' status and return to the main package and then utilise the Dataflow Task Event Handler OnError to exit gracefully.

At the moment I find that the script task in the dataflow returns a .net error popup which I have to then clear. I've tried a Try Catch around the code which seems to stop the debug window appearing but I can't seem to get it to exit the script with a 'failed status' that will cause the package to fail. The Dts.TaskResult = Dts.Results.Failure does not appear to be valid in dataflow tasks. At the moment I'm trying this:

    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

... but all this does is skip the bad row. The dataflow continues. The problem is getting it to exit as 'failed' so the onError error handler event in the package is triggered.

Any suggestions gratefully received.
Glenn

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

迎风吟唱 2024-08-13 06:08:17

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

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

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

Script Transformations don't have the same features for returning success or failure. You can force an error by using this code:

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

Basically, the Error object (function? method? whatever!) will allow you to simulate an error. Meaning, you can make the package error with this code.

森末i 2024-08-13 06:08:17

我已经寻找这个问题的答案有一段时间了。弹出错误对我来说太烦人了!为了避免这种情况,一个“简单”的解决方案(黑客)是这样的:

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

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

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

这可能是一个黑客,但直到有人想出更好的主意...

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

I've been searching for a while to the answer to this question. The popup error is just too annoying for me! To avoid this, a "simple" solution (hack) is this:

Rather than throw an error after the .FireError, create a new DT_UI1 output column in the script transformation, e.g. "ValidationColumn", and set it to 1 or 0 (Not Boolean for reasons that will become clear).

Immediately after the script component, add a derived column transformation, and replace the ValidationColumn with the formula: 1/ValidationColumn. (This does not work with Boolean). This, of course, generateds a divide by zero error, and (using the default setting) fails the derived column transformation and thus immediately the data flow component. Voila!

The error log has the original validation failed message from the .FireError, immediately followed by a divide by zero error.

This may be a hack, but until someone comes up with a better idea...

BTW, I am using this to check that Excel files have the correct headers in the correct place (or alternative places), in conjuction with using IMEX=1, in order to load 2 or more different column variations using a single data flow...

盗梦空间 2024-08-13 06:08:17

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

在我当前的解决方案中,我捕获错误,然后执行 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 次错误后失败。如果没有,脚本将需要实现一个错误输出路径,坦率地说,我没有时间......

In retrospect, the divide by zero error is not necessary.

In my current solution, I am capturing the error, then doing a FireError, then reimplementing the exception handling, like this:

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

This works because it is contained within a Source Script, and would also work in a Transformation Script providing the data flow was set to fail after 1 error. If not, the script would need to implement an error output path which, frankly, I don't have time for...

苦行僧 2024-08-13 06:08:17

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

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

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

请参阅:MSDN - ScriptObjectModel。 TaskResult 属性

在脚本任务代码中使用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

控制流

在此处输入图像描述

Following is a script task I created inside a loop. It is not a direct answer to your question – but the overall idea will help.

The script task is kept inside a sequence container. And the sequence container’s variable named Propagate is set as false. Also, for the sequence container the MaximumErrorCount property is set as zero. So, when an error happen inside the sequence container it is shown in red, OnError event fired – but the loop is continued. It is important to create an onerror event handler for the sequence container for this to work.

Inside the script task, it is forcefully failed inside catch block (by setting task result as Failure). Also the exception message is stored in a variable for storing it into the error logging table. This error data insertion happens from the OnError event handler’s (mentioned above) execute sql task.

Refer: MSDN - ScriptObjectModel.TaskResult Property

Use the TaskResult property of the Dts object in Script task code to notify the package of the success or failure of the Script task.

The catch block inside the script task looks like the one listed below.

  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

Control Flow

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文