0

我有几个 SSIS 包将不同的文件解析到各自的表中。使用 SSIS File Watcher 任务,我想创建一个主包,它将检查文件夹中的文件,然后使用优先约束根据 OutputVariableName 选择正确的子包。我不确定如何编写表达式来正确设置变量。我想根据文件名中的 FINDSTRING() 设置它。

4

1 回答 1

1

您的问题是关于如何在集成服务包中使用来自 Konesan的File Watcher 任务。

OutputVariableName String任务完成时将写入找到的完整文件路径的变量的名称。指定的变量应该是字符串类型

通过http://www.sqlis.com/post/file-watcher-task.aspx

在包级别创建一个名为 CurrentFileName 的 SSIS 变量。配置File Watcher Task属性 OutputVariableName 为User::CurrentFileName。当您将文件放入任务正在监视的文件夹中时,它将为该变量分配完整路径CurrentFileName

您希望使用 FindString 函数对该变量执行某些操作,以帮助确定要触发的包。由于您没有指定我将假设它基于文件名的内容。

很遗憾你强迫一个人使用 FindString 来执行这个任务。我这么说是因为 .NET 库提供了一种出色的静态方法来确定基本文件名,我讨厌看到人们重新发明(和调试)轮子。

我将创建 3 个变量来支持这项工作。

  • BaseFileName - 字符串 - 评估为表达式 = True
  • FileExtensionPosition - Int32 - 评估为 Expression = True
  • LastSlashPosition - Int32 - 评估为 Expression = True

LastSlashPosition使用 FindString 来确定\字符串中的最后一次出现。将FileExtensionPosition确定.字符串中最后一次出现的 。BaseFileName 将使用这些数字来计算对 @[User::CurrentFileName]` 字符串进行切片的位置。

我用来查找字符串中最后一个 X 的懒惰技巧是反转它。然后它是字符串中的第一个元素,我可以将 1 作为最终参数传递给 FindString。

分配给@[User::LastSlashPosition] 的表达式是

FINDSTRING(REVERSE(@[User::CurrentFileName]), "\\", 1)

分配给@[User::FileExtensionPosition] 的表达式是

FINDSTRING(REVERSE(@[User::CurrentFileName]), ".", 1)

然后分配给@[User::BaseFileName] 的表达式变为

SUBSTRING((RIGHT(@[User::CurrentFileName], @[User::LastSlashPosition] -1 )), 1, LEN(RIGHT( @[User::CurrentFileName], @[User::LastSlashPosition] -1)) - @[User::FileExtensionPosition] )

将其分解(RIGHT(@[User::CurrentFileName], @[User::LastSlashPosition] -1 ))为基本文件名。如果 CurrentFileName 等于 J:\ssisdata\so\FileWatcher\CleverFile.txt 则计算结果为“CleverFile.txt”,我将其子串去掉结尾。您可以将其简化为单个子字符串操作,但我的大脑这么晚了。

现在你正在尝试使用,我假设,一系列基于成功优先约束的执行包任务,@[User::BaseFilename] == "SubPackage1你可以这样做,它会正常工作,只是你需要设置每一个,因为你去设置一个新的孩子,你将不得不重复工作。

作为这种方法的替代方法,我将使用 ForEach 枚举器并在其中定义我的所有键值对。

在此处输入图像描述

第 0 列是 BaseFileName 可以评估的值。

第 1 列是我想要触发的 SSIS 包作为响应。

我创建了两个变量来支持这一点并将它们配置为

在此处输入图像描述

我生成的包裹看起来像

在此处输入图像描述

未显示文件观察任务,因为我不想在我的机器上安装它。假设连接到 ForEach 循环。

ForEach 循环遍历上面显示的键值对。容器内的脚本任务只是为优先约束工作提供基础。我将优先约束配置为 Success 和@[User::KeyName] == @[User::BaseFileName]

然后我基于此模拟执行包任务触发。实际的包名称将由 @[User::KeyPackage] 的值驱动

这就是你今天过度设计的解决方案;)

于 2013-09-20T03:11:04.317 回答