第九篇 Integration Services:控制流任务错误

时间:2022-09-25 13:29:13

本篇文章是Integration Services系列的第九篇,详细内容请参考原文


简介
在前面三篇文章,我们创建了一个新的SSIS包,学习了脚本任务和优先约束,并检查包的MaxConcurrentExecutables属性。我们检查、演示并测试优先约束赋值为"成功"、"完成"、"失败"时对工作流的影响。我们学习了SSIS变量和表达式,并将它们应用到优先约束。
这一篇,we introduce fault tolerance by examining methods of task execution state management using the MaximumErrorCount and ForceExecutionResult properties.我们还会学习SSIS控制流任务错误、事件处理程序和容器之间的关系。
SSIS任务错误
打开Precedence.dtsx包。你的控制流面板如图9.1所示:
第九篇 Integration Services:控制流任务错误
图9.1
让我们关注序列容器1。右击Script Task 4选择启用。在我们执行测试前,让我们查看序列容器1中连接Script Task 4、Script Task 2和Script Task 3之间的优先约束配置。Script Task 4和Script Task 3之间的优先约束配置如图9.2所示:
第九篇 Integration Services:控制流任务错误
图9.2
求值运算为表达式和约束,意味着表达式和之前任务(Script Task 4)的执行状态(值)必须为True.在这个例子中,表达式——SSIS变量MyBool(布尔值)必须为True并且之前的任务必须执行失败。
Script Task 2和Script Task 3之间的优先约束配置如图9.3所示:
第九篇 Integration Services:控制流任务错误
图9.3
求值运算为表达式,意味着表达式必须为True.在这个例子中,表达式——SSIS变量MyBool(布尔值)必须为True.优先约束等待之前任务的完成,并且忽略之前任务的执行状态。
测试执行
在BIDS调用器下按F5执行包。当提示Succeed Script Task 4时(图9.4),点击No按钮:
第九篇 Integration Services:控制流任务错误
图9.4
如果你点击No按钮,Script Task 4会失败。然后Script Task 3显示完成消息框,点击确定按钮。你的控制流面板应该如图9.5所示:
第九篇 Integration Services:控制流任务错误
图9.5
Script Task 4失败是因为提示时选择了No.为什么序列容器1失败?
事件"冒泡"
一个错误就是一个事件和事件冒泡。冒泡是什么?BIDS下点击包资源管理器,展开包\可执行文件\序列容器1\可执行文件,包资源管理器应该如图9.6所示:
第九篇 Integration Services:控制流任务错误
图9.6
Script Task 4失败并引起一个错误事件。这就是为什么控制流中Task 4变红。然后错误事件传送(up the line)到序列容器1.因为序列容器内发生一个错误,所以它自己也失败(变红)。错误事件的传输(up in scope)有时叫做冒泡。错误事件没有在序列容器1中停止,它继续冒泡到Precedence包,它也失败。
One way to visualize bubbling from the Package Explorer treeview is to imagine the error event "climbing the tree (view)."错误事件的默认行为会引起控制流中的任务或容器失败并变红。
MaximumErrorCount属性
所有的任务,包括Script Task 4,都有MaximumErrorCount属性。MaximumErrorCount属性的默认值是1,意味着一次错误就会引起任务失败。我将这个属性的值修改为99,如图9.7所示:
第九篇 Integration Services:控制流任务错误
图9.7
当我在BIDS调试器下执行包时,没有任何变化。Script Task 4还是变红,如图9.8所示:
第九篇 Integration Services:控制流任务错误
图9.8
为什么?MaximumErrorCount属性也适用于容器。在一个任务上设置MaximumErrorCount属性没有效果。如果我将序列容器1的MaximumErrorCount属性设置为99会发生什么?如图9.9所示:
第九篇 Integration Services:控制流任务错误
图9.9
序列容器1成功。我经常发现我需要在错误时让包失败。有时,我完全忽略错误。为什么?答案是:忽略错误并不会阻止事件处理程序。在第十篇,我会解释这项行为。MaximumErrorCount属性设置为0(图9.10),有效地忽略容器的错误。
第九篇 Integration Services:控制流任务错误
图9.10
ForceExecutionResult属性
另一个让序列容器1成功的方法是将容器的ForceExecutionResult属性设置为非默认值("None")。在继续前行之前,将MaximumErrorCount属性设置回1。修改序列容器1的ForceExecutionResult属性为"Success",如图9.11所示:
第九篇 Integration Services:控制流任务错误
图9.11
在BIDS调试器下执行包。出现提示信息时,让Script Task 2成功,让Script Task 4失败,接受Script Task 3完成。你的控制流应该如图9.12所示:
第九篇 Integration Services:控制流任务错误
图9.12
即使MaximumErrorCount属性设置为1,序列容器1成功。ForceExecutionResult属性覆盖了MaximumErrorCount属性。
错误事件
控制流任务的每一次失败会引起一个错误事件。The error event properties are populated when it is raised, and these properties remain static as the event message is transmitted “up the tree.”通过添加一个脚本任务为Script Task 4创建"OnError"事件处理程序。
首先,在控制流点击Script Task 4。接着,点击事件处理程序页签(图9.13):
第九篇 Integration Services:控制流任务错误
图9.13
事件处理程序打开,默认显示控制流所选任务对应的未配置的"OnError"事件处理程序。如图9.14所示:
第九篇 Integration Services:控制流任务错误
图9.14
注意你可以通过点击可执行文件下拉菜单,导航到SSIS包中的其他可执行文件,如图9.15所示:
第九篇 Integration Services:控制流任务错误
图9.15
你也可以通过事件处理程序下拉菜单,为你想创建的事件处理程序选择事件,如图9.16所示:
第九篇 Integration Services:控制流任务错误
图9.16
可执行文件下拉菜单选择Script Task 4,事件处理程序下拉菜单选择OnError.为了配置事件处理程序,点击链接标记"单击此处为可执行文件"Script Task 4"创建一个"OnError"事件处理程序",如图9.17所示:
第九篇 Integration Services:控制流任务错误
图9.17
点击链接为Script Task 4创建一个OnError事件处理程序。看一看OnError事件处理程序的工具箱,如图9.18所示:
第九篇 Integration Services:控制流任务错误
图9.18
看起来很熟悉?它应该是——它就是控制流工具箱!这意味着事件处理程序提供SSIS工作流来响应事件。事件处理程序包括一组用于处理事件的变量,它们如图9.19所示:
第九篇 Integration Services:控制流任务错误
图9.19
注意这些都是系统变量,除非你点击了显示系统变量按钮(图9.20)才会显示。
第九篇 Integration Services:控制流任务错误
图9.20
为了演示变量在事件处理程序如何工作,拖一个脚本任务到事件处理程序。打开脚本任务编辑器,修改ScriptLanguage为"Microsoft Visual Basic 2008".点击ReadOnlyVariables属性,然后点击文体框的省略号。打开选择变量对话框,选择变量System::ErrorCode,System::ErrorDescription和System::SourceName,如图9.21所示:
第九篇 Integration Services:控制流任务错误
图9.21
点击确定按钮,关闭选择变量窗口。脚本任务编辑器的脚本页如图9.22所示:
第九篇 Integration Services:控制流任务错误
图9.22
点击编辑脚本按钮打开"ssisscript–Integration Services 脚本任务"编辑器。用下面的VB代码替换Public Sub Main()中的代码:

      Public Sub Main()
Dim iErrorCode As Integer = _
Convert.ToInt32(Dts.Variables("ErrorCode").Value)
Dim sErrorDescription As String = _
Dts.Variables("ErrorDescription").Value.ToString
Dim sSourceName As String = _
Dts.Variables("SourceName").Value.ToString
Dim sSubComponent As String = _
"Script Task 4 OnError Event Handler"
Dim sMsg As String = "Source: " & sSourceName & vbCrLf & _
"Error Code: " & iErrorCode.ToString & _
vbCrLf & _
"Error Description: " & _
sErrorDescription MsgBox(sMsg, , sSubComponent) Dts.TaskResult = ScriptResults.Success End Sub

代码9.1
代码9.1中的VB代码创建三个VB脚本变量-iErrorCode、sErrorDescription and sSourceName-mapping each to similarly-named SSIS variables scoped to the OnError event handler.映射发生在两个步骤。第一个步骤是图9.21配置的ReadOnlyVariables属性。这将SSIS变量暴露给脚本任务。第二个步骤是Dts命名空间中的变量对象,这使我们能够访问脚本任务ReadOnlyVariables属性中的变量集合。
脚本任务ReadOnlyVariables属性中的SSIS变量列表是脚本任务中可用的变量集合。我们使用Dts.Variables对象访问这些可用的SSIS变量:

Dts.Variables("<Variable Name>").Value

代码9.2
从Dts.Variables访问变量的值属性是一个对象。我们要将这个对象转换成其他数据类型(比如String and Integer)。值属性包含一个".ToString"方法会尝试将对象转换为String数据类型。
脚本任务错误
如果脚本任务不能定位脚本任务的ReadOnlyVariables属性中的SSIS变量,它会抛出类似下面的错误:
错误: 无法锁定变量“System::ErrorCod”进行读访问,错误为 0xC0010001“找不到变量。如果在包的执行期间试图从容器的 Variables 集合检索某个变量,但该变量不在此处时,将出现这种情况。变量可能已更改名称,或者并未创建。”。
我通过删除脚本任务的ReadOnlyVariables属性中System::ErrorCode变量的最后一个字母"e"产生这个错误。右击脚本任务选择执行任务,如图9.23所示:
第九篇 Integration Services:控制流任务错误
图9.23
任务执行失败,在进度(执行结果)页签出现错误信息,如图9.24所示:
第九篇 Integration Services:控制流任务错误
图9.24
为什么错误是:无法锁定变量。这是一个很棒的问题。在脚本任务开始使用SSIS变量,需要锁定它们。这项行为的解释超出了本篇文章。在脚本任务成功锁定SSIS变量后,脚本任务就能访问SSIS变量。
如果你试图在脚本任务访问一个不存在于ReadOnlyVariables或ReadWriteVariables脚本任务属性的SSIS变量名称,或者你拼错了SSIS变量名称,或者甚至是你没有匹配SSIS变量名称的大小写,就会产生另一个脚本任务错误。你可以通过下面方法产生这个错误。首先修正脚本任务的ReadOnlyVariables中的System::ErrorCode变量名称,然后打开脚本任务脚本编辑器。修改iErrorCode变量的声明如代码9.3所示:

Dim iErrorCode As Integer = _
Convert.ToInt32(Dts.Variables("errorCode").Value)

代码9.3
注意唯一的修改是将SSIS变量的名称"ErrorCode"修改为"errorCode"。在进度(执行结果)页签产生的错误非常长,但是以下面开始:
错误: System.Reflection.TargetInvocationException: 调用的目标发生了异常。 ---> Microsoft.SqlServer.Dts.Runtime.DtsRuntimeException: 在集合中找不到元素。如果在包的执行期间试图从容器的集合检索某个元素,但该元素不在此处,将发生此错误。
在进度(执行结果)页签,错误信息如图9.25所示:
第九篇 Integration Services:控制流任务错误
图9.25
这些错误很难解决。
修正脚本任务中的脚本中的拼写"ErrorCode"。在事件处理程序执行脚本任务,结果类似图9.26:
第九篇 Integration Services:控制流任务错误
图9.26
观察错误
在BIDS调试器下执行Precedence包。当提示succeed Script Task 4(图9.27),点击No按钮:
第九篇 Integration Services:控制流任务错误
图9.27
点击No引起Script Task 4失败,产生一个错误事件。这个错误事件被OnError事件处理程序监听到,引起OnError事件处理程序上的脚本任务执行并显示错误信息,如图9.28所示:
第九篇 Integration Services:控制流任务错误
图9.28
更多关于冒泡
前面,我们提到事件冒泡。例子中,Script Task 4产生的错误事件会传输(up the tree)到序列容器1。如果我们为序列容器1配置一个OnError事件处理程序,我们可以观察这个发生。
停止BIDS调试器,在控制流选择序列容器1,点击事件处理程序页签。像以前一样,点击"单击此处为可执行文件"序列容器1"创建一个"OnError"事件处理程序"的链接。在Script Task 4事件处理程序拷贝脚本任务,然后将它粘贴到序列容器1的事件处理程序,如图9.29所示:
第九篇 Integration Services:控制流任务错误
图9.29
打开脚本任务编辑器,点击编辑脚本按钮。修改Public Sub Main()中的sSubComponent行为:

Dim sSubComponent As String = _
"Sequence Container 1 OnError Event Handler"

代码9.4
右击脚本任务,选择执行任务。你的结果类似于图9.30:
第九篇 Integration Services:控制流任务错误
图9.30
在BIDS调试器下执行整个SSIS包。当提示succeed Script Task 4时,点击No按钮产生一个错误事件。
像以前一样,OnError事件处理程序监听并响应Script Task 4错误事件,如图9.31所示:
第九篇 Integration Services:控制流任务错误
图9.31
你可以说它是Script Task 4OnError事件处理程序的响应,因为消息对话框的标题包含"Script Task 4 OnError Event Handler"文本。同样正在执行的脚本任务是黄色的,并且它是在Script Task 4的OnError事件处理程序中。
点击确定,错误事件冒泡到序列容器1的OnError事件处理程序,如图9.32所示:
第九篇 Integration Services:控制流任务错误
图9.32
依据消息对话框的标题你可以分辨这是序列容器1的事件处理程序。
注意消息对话框中的内容。错误事件的源是Script Task 4,错误描述和错误代码值没有变更。在SSIS事件中这是非常有趣的行为。当一个SSIS任务最初产生事件就会填充事件属性。一旦事件放到消息总线,它们的值就不会变更。
事件会从序列容器1继续冒泡到Precedence.dtsx包。变量的值将保持静态,任何配置的监听都显示源:Script Task 4,错误代码:8,错误描述:脚本返回了失败结果。
总结
在这一篇,我们学习了SSIS控制流任务错误行为,包括错误事件、OnError事件处理程序和错误冒泡。我们演示了事件冒泡和容器的关系,还介绍了MaximumErrorCount和ForceExecutionResult容错属性。

第九篇 Integration Services:控制流任务错误的更多相关文章

  1. 【译】第九篇 Integration Services:控制流任务错误

    本篇文章是Integration Services系列的第九篇,详细内容请参考原文. 简介在前面三篇文章,我们创建了一个新的SSIS包,学习了脚本任务和优先约束,并检查包的MaxConcurrentE ...

  2. 第十三篇 Integration Services:SSIS变量

    本篇文章是Integration Services系列的第十三篇,详细内容请参考原文. 简介在前一篇我们结合了之前所学的冒泡.日志记录.父子模式创建一个自定义的SSIS包日志记录模式.在这一篇,我们将 ...

  3. 第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

  4. 第十一篇 Integration Services:日志记录

    本篇文章是Integration Services系列的第十一篇,详细内容请参考原文. 简介在前一篇,我们讨论了事件行为.我们分享了操纵事件冒泡默认行为的方法,介绍了父子模式.在这一篇,我们会配置SS ...

  5. 第十篇 Integration Services:高级事件行为

    本篇文章是Integration Services系列的第十篇,详细内容请参考原文. 简介在前一篇, we introduced fault tolerance by examining method ...

  6. 【译】第十三篇 Integration Services:SSIS变量

    本篇文章是Integration Services系列的第十三篇,详细内容请参考原文. 简介在前一篇我们结合了之前所学的冒泡.日志记录.父子模式创建一个自定义的SSIS包日志记录模式.在这一篇,我们将 ...

  7. 【译】第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

  8. 【译】第十一篇 Integration Services:日志记录

    本篇文章是Integration Services系列的第十一篇,详细内容请参考原文. 简介在前一篇,我们讨论了事件行为.我们分享了操纵事件冒泡默认行为的方法,介绍了父子模式.在这一篇,我们会配置SS ...

  9. 【译】第十篇 Integration Services:高级事件行为

    本篇文章是Integration Services系列的第十篇,详细内容请参考原文. 简介在前一篇, we introduced fault tolerance by examining method ...

随机推荐

  1. JavaScript中常见的数组操作函数及用法

    JavaScript中常见的数组操作函数及用法 昨天写了个帖子,汇总了下常见的JavaScript中的字符串操作函数及用法.今天正好有时间,也去把JavaScript中常见的数组操作函数及用法总结一下 ...

  2. HDU 1811 Rank of Tetris(拓扑排序&plus;并查集)

    题目链接: 传送门 Rank of Tetris Time Limit: 1000MS     Memory Limit: 32768 K Description 自从Lele开发了Rating系统, ...

  3. 离线更新SEPM服务器的病毒定义库

    1. 从http://www.symantec.com/security_response/definitions/download/detail.jsp?gid=sep下载JDB文件    2. 将 ...

  4. 内存溢出之Tomcat内存配置

    设置Tomcat启动的初始内存其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4. 可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置 三.实例,以下给 ...

  5. linux下alias命令详解

    功能说明:设置指令的别名. 语 法:alias[别名]=[指令名称] 形如: alias cp=“cp -i” : 补充说明:用户可利用alias,自定指令的别名.若仅输入alias,则可列出目前所有 ...

  6. 【M31】让函数根据一个以上的对象类型来决定如何虚化

    1.考虑下面的问题,游戏软件中有角色A,B,角色又可以细化为A1,A2,A3:B1,B2,B3,两类角色之间相互攻击.即A1可以攻击B1,B2,B3,B1可以攻击A1,A2,A3.C++的多态,只根据 ...

  7. 第二篇:web之前端之css

    前端之css   前端之css 本节内容 css概述及引入 css选择器 css常用属性 1.css概述及引入 CSS概述 CSS是Cascading Style Sheets的简称,中文称为层叠样式 ...

  8. JAVA中this用法小结&lbrack;转&rsqb;

    Java关键字this只能用于方法方法体内.当一个对象创建后,Java虚拟机(JVM)就会给这个对象分配一个引用自身的指针,这个指针的名字就是 this.因此,this只能在类中的非静态方法中使用,静 ...

  9. &lbrack;Android代码阅读&rsqb;分类简介

    分类简介: 阅读他人的代码,可以学到很多东西,从思路,到方案,一系列都可以在项目代码中体现,所以,此分类专门用于记录阅读过的项目代码,并在上面给出自己的理解和注释 在此,感谢原作者开源分享项目代码

  10. 如何让一个DIV水平,垂直方向都居中于浏览器?

    <style type="text/css"><!-- div {position:absolute;top:50%;left:50%;margin:-150px ...