1

我刚刚创建了 ssis 包。Foreach 循环将源作为表达式,当我提供错误的源路径时,我希望它失败。相反,它成功了。我在其他任何地方都没有找到任何解释。验证时不应该失败吗?任何关于此的词都会帮助我理解。

谢谢, L

4

1 回答 1

3

信息

如果没有要枚举的对象,Foreach 枚举器不会失败。这是团队做出的设计决定。想象一下,您必须在每个包中做多少工作才能处理 No EnumeratorType Found 错误。

正如您所发现的,这种选择的缺点是无效路径不会导致异常。FileSpec如果没有找到匹配的文件以及权限阻止帐户访问目录/文件,您也会遇到相同的情况。

但是,如果您查看执行,SSIS会告诉您它没有找到任何东西。正如一位同事所说,“警告只是尚未长大的错误”。

2008 年的警告看起来像

警告:Foreach 循环容器中的 0x8001C004:For Each 文件枚举器为空。For Each File 枚举器未找到任何与文件模式匹配的文件,或者指定的目录为空。

在 2012 年,来自 SSISDB 表的情况稍微复杂一些,catalog.operation_messages但仍然表明它什么也没找到。

FELC 处理文件:警告:For Each File 枚举器为空。For Each File 枚举器未找到任何与文件模式匹配的文件,或者指定的目录为空。

行动

如果您不喜欢这种行为,可以采取不同的方法来解决它。

首先是将警告视为错误。这是dtexec的一个参数,/W或者/WarnAsError如果您不了解整个简洁性。不过,这会将所有警告视为错误,因此如果您的数据流有未使用的列但找到了文件,您的包仍将无法通过验证。我自己喜欢这种方法,因为当我的包裹无人看管时我不希望出现警告。你的宽容我因人而异。此外,这是运行 SSIS 包的非标准参数,知识较少的同事可能会在作业创建步骤中省略该参数,并且您的包不会崩溃。

二是自己处理。两个直接的实现是在你的 ForEach 枚举器之后有一个脚本任务,它返回Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure这个脚本任务被一个在 ForEach 枚举器内设置为 True 的变量禁用/启用。如果 ForEach 的内部从未被击中,我们的变量永远不会设置为 True,因此容器外部的 Script Task 上的 Disabled 属性仍然为 False,所以事情就会爆炸。

另一个想法是将 OnWarning 事件处理程序添加到 ForEach 枚举器。然后,您需要解析ErrorCode/ErrorDescription系统变量以获得适当的值。看来,错误代码是-2147368956,而描述是The For Each File enumerator is empty. The For Each File enumerator did not find any files that matched the file pattern, or the specified directory was empty.\r\n

同样,一旦发现这些警告,您就需要添加代码来破坏执行。将返回值设置为 DTSExecResult.Failure 的脚本任务通常是最干净的机制。

于 2014-08-17T17:03:29.280 回答