根据平面文件名执行不同的SSIS包

时间:2013-09-19 19:27:38

标签: ssis flat-file

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

1 个答案:

答案 0 :(得分:1)

您的问题是如何在集成服务包中使用Konesans中的File Watcher Task

  

OutputVariableName String 在完成任务时将写入完整文件路径的变量的名称。指定的变量应为string

类型

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

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

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

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

我会创建3个变量来支持这项努力。

  • BaseFileName - String - 评估为Expression = 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枚举器并在那里定义我的所有键值对。

enter image description here

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

第1列是我想要响应的SSIS包。

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

enter image description here

我的结果包看起来像

enter image description here

未显示File Watcher Task,因为我不想在我的机器上安装它。假设连接到ForEach循环。

ForEach循环旋转上面显示的键值对。容器内的Script Task只是为Precedence Constraint提供了一个工作基础。我将优先约束配置为Success和@[User::KeyName] == @[User::BaseFileName]

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

的值驱动

那是你当天过度设计的解决方案;)