我有几个SSIS包,可以将不同的文件解析到各自的表中。使用SSIS文件观察器任务,我想创建一个主包,它将检查文件的文件夹,然后使用优先约束基于OutputVariableName选择正确的子包。我不确定如何编写表达式来正确设置变量。我想根据文件名中的FINDSTRING()来设置它。
答案 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个变量来支持这项努力。
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包。
我创建了两个变量来支持它并将它们配置为
我的结果包看起来像
未显示File Watcher Task,因为我不想在我的机器上安装它。假设连接到ForEach循环。
ForEach循环旋转上面显示的键值对。容器内的Script Task只是为Precedence Constraint提供了一个工作基础。我将优先约束配置为Success和@[User::KeyName] == @[User::BaseFileName]
然后我基于此模拟执行包任务。实际的包名称将由@ [User :: KeyPackage]
的值驱动那是你当天过度设计的解决方案;)