本篇文章是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所示:

图9.1
让我们关注序列容器1。右击Script Task 4选择启用。在我们执行测试前,让我们查看序列容器1中连接Script Task 4、Script Task 2和Script Task 3之间的优先约束配置。Script Task 4和Script Task 3之间的优先约束配置如图9.2所示:

图9.2
求值运算为表达式和约束,意味着表达式和之前任务(Script Task 4)的执行状态(值)必须为True.在这个例子中,表达式——SSIS变量MyBool(布尔值)必须为True并且之前的任务必须执行失败。
Script Task 2和Script Task 3之间的优先约束配置如图9.3所示:

图9.3
求值运算为表达式,意味着表达式必须为True.在这个例子中,表达式——SSIS变量MyBool(布尔值)必须为True.优先约束等待之前任务的完成,并且忽略之前任务的执行状态。
测试执行
在BIDS调用器下按F5执行包。当提示Succeed Script Task 4时(图9.4),点击No按钮:

图9.4
如果你点击No按钮,Script Task 4会失败。然后Script Task 3显示完成消息框,点击确定按钮。你的控制流面板应该如图9.5所示:

图9.5
Script Task 4失败是因为提示时选择了No.为什么序列容器1失败?
事件"冒泡"
一个错误就是一个事件和事件冒泡。冒泡是什么?BIDS下点击包资源管理器,展开包\可执行文件\序列容器1\可执行文件,包资源管理器应该如图9.6所示:

图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所示:

图9.7
当我在BIDS调试器下执行包时,没有任何变化。Script Task 4还是变红,如图9.8所示:

图9.8
为什么?MaximumErrorCount属性也适用于容器。在一个任务上设置MaximumErrorCount属性没有效果。如果我将序列容器1的MaximumErrorCount属性设置为99会发生什么?如图9.9所示:

图9.9
序列容器1成功。我经常发现我需要在错误时让包失败。有时,我完全忽略错误。为什么?答案是:忽略错误并不会阻止事件处理程序。在第十篇,我会解释这项行为。MaximumErrorCount属性设置为0(图9.10),有效地忽略容器的错误。

图9.10
ForceExecutionResult属性
另一个让序列容器1成功的方法是将容器的ForceExecutionResult属性设置为非默认值("None")。在继续前行之前,将MaximumErrorCount属性设置回1。修改序列容器1的ForceExecutionResult属性为"Success",如图9.11所示:

图9.11
在BIDS调试器下执行包。出现提示信息时,让Script Task 2成功,让Script Task 4失败,接受Script Task 3完成。你的控制流应该如图9.12所示:

图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):

图9.13
事件处理程序打开,默认显示控制流所选任务对应的未配置的"OnError"事件处理程序。如图9.14所示:

图9.14
注意你可以通过点击可执行文件下拉菜单,导航到SSIS包中的其他可执行文件,如图9.15所示:

图9.15
你也可以通过事件处理程序下拉菜单,为你想创建的事件处理程序选择事件,如图9.16所示:

图9.16
可执行文件下拉菜单选择Script Task 4,事件处理程序下拉菜单选择OnError.为了配置事件处理程序,点击链接标记"单击此处为可执行文件"Script Task 4"创建一个"OnError"事件处理程序",如图9.17所示:

图9.17
点击链接为Script Task 4创建一个OnError事件处理程序。看一看OnError事件处理程序的工具箱,如图9.18所示:

图9.18
看起来很熟悉?它应该是——它就是控制流工具箱!这意味着事件处理程序提供SSIS工作流来响应事件。事件处理程序包括一组用于处理事件的变量,它们如图9.19所示:

图9.19
注意这些都是系统变量,除非你点击了显示系统变量按钮(图9.20)才会显示。

图9.20
为了演示变量在事件处理程序如何工作,拖一个脚本任务到事件处理程序。打开脚本任务编辑器,修改ScriptLanguage为"Microsoft Visual Basic 2008".点击ReadOnlyVariables属性,然后点击文体框的省略号。打开选择变量对话框,选择变量System::ErrorCode,System::ErrorDescription和System::SourceName,如图9.21所示:

图9.21
点击确定按钮,关闭选择变量窗口。脚本任务编辑器的脚本页如图9.22所示:

图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所示:

图9.23
任务执行失败,在进度(执行结果)页签出现错误信息,如图9.24所示:

图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所示:

图9.25
这些错误很难解决。
修正脚本任务中的脚本中的拼写"ErrorCode"。在事件处理程序执行脚本任务,结果类似图9.26:

图9.26
观察错误
在BIDS调试器下执行Precedence包。当提示succeed Script Task 4(图9.27),点击No按钮:

图9.27
点击No引起Script Task 4失败,产生一个错误事件。这个错误事件被OnError事件处理程序监听到,引起OnError事件处理程序上的脚本任务执行并显示错误信息,如图9.28所示:

图9.28
更多关于冒泡
前面,我们提到事件冒泡。例子中,Script Task 4产生的错误事件会传输(up the tree)到序列容器1。如果我们为序列容器1配置一个OnError事件处理程序,我们可以观察这个发生。
停止BIDS调试器,在控制流选择序列容器1,点击事件处理程序页签。像以前一样,点击"单击此处为可执行文件"序列容器1"创建一个"OnError"事件处理程序"的链接。在Script Task 4事件处理程序拷贝脚本任务,然后将它粘贴到序列容器1的事件处理程序,如图9.29所示:

图9.29
打开脚本任务编辑器,点击编辑脚本按钮。修改Public Sub Main()中的sSubComponent行为:

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

代码9.4
右击脚本任务,选择执行任务。你的结果类似于图9.30:

图9.30
在BIDS调试器下执行整个SSIS包。当提示succeed Script Task 4时,点击No按钮产生一个错误事件。
像以前一样,OnError事件处理程序监听并响应Script Task 4错误事件,如图9.31所示:

图9.31
你可以说它是Script Task 4OnError事件处理程序的响应,因为消息对话框的标题包含"Script Task 4 OnError Event Handler"文本。同样正在执行的脚本任务是黄色的,并且它是在Script Task 4的OnError事件处理程序中。
点击确定,错误事件冒泡到序列容器1的OnError事件处理程序,如图9.32所示:

图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. UVa 11624 Fire!(BFS)

    Fire! Time Limit: 5000MS   Memory Limit: 262144KB   64bit IO Format: %lld & %llu Description Joe ...

  2. MarkDown编辑器用法

    代码行1 var s = "JavaScript syntax highlighting"; alert(s); 代码行2:ESC下面的英文3个波浪号~按键 var s = &qu ...

  3. 解析使用ThinkPHP应该掌握的调试手段

    解析使用ThinkPHP应该掌握的调试手段     使用ThinkPHP应该掌握的调试手段经常看到有人问到findAll的返回数据类型是什么之类的问题,以及出错了不知道什么原因的情况,其实还是没有熟悉 ...

  4. php开源项目

    论坛社区:Discuz.PHPWind.ThinkSAAS.phpBB CMS内容管理:DedeCMS.PHPCMS.帝国CMS.齐博CMS.Drupal 企业建站:CmsEasy.KingCMS.P ...

  5. Yii源码阅读笔记(三)

    接着上次的继续阅读BaseYii.php vendor/yiisoft/yii2/BaseYii.php—— public static function getRootAlias($alias)// ...

  6. A20的板子笔记

    除了串口可以登入控制台,还可以用SSH2. ftp连接的时候要打开  vi /usr/sbin/stupid-ftpd.conf 修改端口,修改完端口,登入的时候root的密码跟以前不一样,可以从st ...

  7. writing concurrent programs

    Computer Systems A Programmer's Perspective Second Edition To this point in our study of computer sy ...

  8. Android 一键直接查看Sqlite数据库数据

    转自:http://www.cnblogs.com/trinea/archive/2012/11/16/2773656.html 本文主要介绍Android开发中如何一键直接查看sqlite数据库中的 ...

  9. 【转】Problems with HTTPS, HttpWebRequest, and iOS?

    We're using HttpWebRequest to hit HTTPS urls, on iOS. In Debug, local builds, etc. everything works ...

  10. PLSQL 设置

    设置plsql使用特定的oracle数据库客户端来与数据库进行交互