我刚刚创建了ssis包。 Foreach循环将源作为表达式,我希望它在我提供错误的源路径时失败。取而代之的是成功。我在其他任何地方都没有找到任何解释。在验证时不应该失败吗?任何关于此的话都会帮助我理解。
谢谢, →
答案 0 :(得分:2)
如果没有要枚举的对象,Foreach枚举器不会失败。这是团队采取的设计决策。想象一下,你需要在每个包中做更多的工作来处理No EnumeratorType Found error。
正如您所发现的,此选择的缺点是无效路径不会导致异常。如果找不到与FileSpec
匹配的文件,以及权限阻止帐户访问目录/文件,您也会遇到相同的情况。
但是,如果你看一下执行,SSIS 会告诉你你没找到任何东西。正如一位同事所说,"警告只是没有成长的错误"。
2008年的警告看起来像是
警告:Foreach循环容器中的0x8001C004:For Each File枚举器为空。 For Each File枚举器未找到与文件模式匹配的任何文件,或指定的目录为空。
2012年,它来自SSISDB catalog.operation_messages
表更精细,但仍传达它没有发现任何内容。
FELC处理文件:警告:For Each File枚举器为空。 For Each File枚举器未找到与文件模式匹配的任何文件,或指定的目录为空。
如果您不喜欢此行为,可以采取不同的方法来解决此问题。
首先是将警告视为错误。如果您不是整个简洁的事情,这是/W
或/WarnAsError
dtexec的参数。这会将所有警告视为错误,但如果您的数据流有未使用的列但找不到文件,那么您的包仍然无法通过验证。我自己喜欢这种方法,因为当我的包无人值守时,我不想要警告。你的宽容我的变化。此外,这是运行SSIS包的非标准参数,知识渊博的同事可能会在作业创建步骤中省略该参数,并且您的包不会爆炸。
第二是自己处理它。两个立即实现将是在ForEach枚举器之后返回Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
之后的脚本任务。此脚本任务由变量禁用/启用,该变量在ForEach枚举器内设置为True。如果从未击中ForEach的内部,我们的Variable永远不会设置为True,因此容器外部的Script Task上的Disabled属性保持为False,因此事情就会爆炸。
另一个想法是向ForEach枚举器添加一个OnWarning事件处理程序。然后,您需要解析ErrorCode
/ ErrorDescription
系统变量以获取适当的值。看来,ErrorCode为-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的脚本任务通常是最干净的机制。