加入收藏 | 设为首页 | 会员中心 | 我要投稿 东莞站长网 (https://www.0769zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

ssis – 如何在Foreach文件枚举器上为FileSpec属性设置表达式?

发布时间:2021-03-08 07:43:37 所属栏目:MsSql教程 来源:网络整理
导读:我正在尝试创建一个SSIS包来处理包含多年文件的目录中的文件.这些文件都是以数字命名的,所以为了保存处理所有内容,我想传递SSIS最小数量,并且只枚举其名称(转换为数字)高于我的最小值的文件. 我试过让ForEach File循环枚举所有内容然后排除脚本任务中的文件,

我正在尝试创建一个SSIS包来处理包含多年文件的目录中的文件.这些文件都是以数字命名的,所以为了保存处理所有内容,我想传递SSIS最小数量,并且只枚举其名称(转换为数字)高于我的最小值的文件.

我试过让ForEach File循环枚举所有内容然后排除脚本任务中的文件,但是当处理成千上万的文件时,这太慢而不适合.

FileSpec属性允许您指定一个文件掩码来指示您在集合中需要哪些文件,但我无法完全看到如何指定表达式以使其工作,因为它本质上是一个字符串匹配.

如果组件内部有一个表达式,基本上说我应该枚举吗? – 是/否,这将是完美的.我一直在尝试使用下面的表达式,但找不到要应用它的属性.

(DT_I4)REPLACE( SUBSTRING(@[User::ActiveFilePath],FINDSTRING( @[User::ActiveFilePath],“”,7 ) + 1,100),”.txt”,””) > @[User::MinIndexId] ? “True” : “False”

解决方法

这是一种可以实现这一目标的方法.您可以使用表达式任务与Foreach循环容器相结合来匹配文件名的数值.这是一个说明如何执行此操作的示例.该示例使用SSIS 2012.

这可能效率不高,但它是这样做的一种方式.

假设有一个文件夹,其中包含以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.

希望有所帮助.

(编辑:东莞站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读