我试过让ForEach File循环枚举所有内容然后排除脚本任务中的文件,但是当处理成千上万的文件时,这太慢而不适合.
FileSpec属性允许您指定一个文件掩码来指示您在集合中需要哪些文件,但我无法完全看到如何指定表达式以使其工作,因为它本质上是一个字符串匹配.
如果组件内部有一个表达式,基本上说我应该枚举吗? – 是/否,这将是完美的.我一直在尝试使用下面的表达式,但找不到要应用它的属性.
(DT_I4)REPLACE( SUBSTRING(@[User::ActiveFilePath],FINDSTRING( @[User::ActiveFilePath],“\”,7 ) + 1,100),”.txt”,””) > @[User::MinIndexId] ? “True” : “False”
解决方法
这可能效率不高,但它是这样做的一种方式.
假设有一个文件夹,其中包含以YYYYMMDD格式命名的一堆文件.该文件夹包含自1921年以来每个月第一天的文件,如19210101,19210201,19210301 ……所有截至当前月份20121101.最多可添加1,103个文件.
假设要求只是循环自1948年6月以来创建的文件.这意味着SSIS包只需要遍历大于19480601的文件.
在SSIS包上,创建以下三个参数.最好为这些配置参数,因为这些值可以跨环境配置.
> ExtensionToMatch – String数据类型的此参数将包含程序包必须循环的扩展.这将补充将在Foreach循环容器上使用的FileSpec变量的值.
> FolderToEnumerate – String数据类型的此参数将存储包含要循环的文件的文件夹路径.
> MinIndexId – Int32数据类型的此参数将包含文件应与模式匹配的最小数值.
创建以下四个参数,帮助我们遍历文件.
> ActiveFilePath – String数据类型的变量将保存文件名,因为Foreach循环容器循环遍历文件夹中的每个文件.此变量用于表达另一个变量.为避免错误,请将其设置为非空值,例如1.
> FileCount – 这是一个Int32数据类型的虚拟变量,将用于此示例,以说明Foreach循环容器将循环的文件数.
> FileSpec – String数据类型的这个变量将保持文件模式循环.将此变量的表达式设置为下面提到的值.此表达式将使用参数上指定的扩展名.如果没有扩展名,它将*.*循环遍历所有文件.
“*” + (@[$Package::ExtensionToMatch] == “” ? “.*” : @[$Package::ExtensionToMatch])
> ProcessThisFile – 此布尔数据类型的变量将评估特定文件是否与条件匹配.
配置包如下所示. Foreach循环容器将循环遍历与FileSpec变量上指定的模式匹配的所有文件.表达式任务上指定的表达式将在运行时期间进行评估,并将填充变量ProcessThisFile.然后,该变量将用于Precedence约束,以确定是否处理该文件.
对于成功匹配表达式的每个文件,Foreach循环容器中的脚本任务将使变量FileCount的计数器增加1.
Foreach循环外部的脚本任务将仅显示Foreach循环容器循环的文件数.
配置Foreach循环容器以使用参数和使用变量的文件循环遍历文件夹.
当循环遍历每个文件时,将文件名存储在变量ActiveFilePath中.
在Expression任务上,将表达式设置为以下值.表达式将没有扩展名的文件名转换为数字,然后检查它是否在参数MinIndexId中的计算结果大于给定数字
@[User::ProcessThisFile] = (DT_BOOL)((DT_I4)(REPLACE(@[User::ActiveFilePath],@[User::FileSpec],””)) > @[$Package::MinIndexId] ? 1: 0)
右键单击Precedence约束并将其配置为在表达式上使用变量ProcessThisFile.这告诉包只有在与表达式任务上设置的条件匹配时才处理该文件.
@[User::ProcessThisFile]
在第一个脚本任务中,我将变量User :: FileCount设置为ReadWriteVariables,并在脚本任务中设置以下C#代码.这会增加成功匹配条件的文件的计数器.
public void Main() { Dts.Variables["User::FileCount"].Value = Convert.ToInt32(Dts.Variables["User::FileCount"].Value) + 1; Dts.TaskResult = (int)ScriptResults.Success; }
在第二个脚本任务中,我将变量User :: FileCount设置为ReadOnlyVariables,并在脚本任务中设置以下C#代码.这只是输出已处理的文件总数.
public void Main() { MessageBox.Show(String.Format("Total files looped through: {0}",Dts.Variables["User::FileCount"].Value)); Dts.TaskResult = (int)ScriptResults.Success; }
当MinIndexId设置为1948061(不包括此项)执行包时,它输出值773.
当MinIndexId设置为20111201(不包括此项)执行包时,它输出值11.
希望有所帮助.