我有一个包含文件的列表加载到数据库中的文本文件。
该列表包含两列:
FilePath,Type
c:\f1.txt,A
c:\f2.txt,B
c:\f3.txt,B
我想提供此文件作为源SSIS。 然后,我希望它通过线穿境而过线。 对于每一行,我希望它读取文件路径列中的文件,并检查类型。
如果类型是A,那么我希望它忽略前4行位于在当前行的文件路径列中的文件,然后在表中加载该文件内的数据的其余部分。 如果类型是B,则我希望它打开的文件和所述文件的第一列复制到表1和第二列到表2用于所有行的。
我真的很感激,如果有人可以请提供我的,我需要按照步骤的高级列表。
任何帮助表示赞赏。
这是SSIS中做的一种方式。 下面的步骤是相对于SSIS 2008 R2。
- 创建一个SSIS包并创建三个包变量分别是
FileName
, FilesToRead
和Type
。 FilesToRead变量将持有的文件列表和它们的类型信息。 我们将有一个循环,将通过每这些记录和信息存储在文件名和类型变量每次通过循环时间。
- 在控制流选项卡,将一个数据流任务,然后foreach循环容器。 数据流任务将读取包含有要处理的文件列表中的文件。 然后这个循环遍历每个文件。 控制流片最终会是这个样子。 现在,会有误差,因为没有配置。 我们将得到的是短期内。
- 在连接管理器部分,你需要四个连接。
- 首先,你需要一个OLE DB连接来连接到数据库。 这个命名为
SQLServer
。 - 其次,平面文件连接管理器读取包含文件和类型列表中的文件。 此平面文件连接管理器将包含配置,即两列
FileName
和Type
名称这是Files
。 - 第三,另一个平面文件连接管理器读取类型A.名称将此作为所有文件
Type_A
。 在此平面文件连接管理器,然后在文本框中的值4 Header rows to skip
,使得第一四行总是跳过。 - 第四,多了一个平面文件连接管理器读取类型B.名称的所有文件,这是
Type_B
。
- 让我们回到控制流。 第一个数据流任务双击。 数据流任务内,放置将使用连接管理器读取所有文件的平面文件的源
Files
,然后将一个Recordset Destination
。 配置变量FilesToRead
在记录目的地。 你的第一个数据流任务想,如下图所示。
- 现在,让我们再回去控制流选项卡。 配置ForEach循环如下所示。 这个循环将通过存储在变量记录
FilesToRead
。 因为,记录包含两列,每一个记录通过循环时,变量FileName
和Type
将被赋予当前记录的值。
- 在内部,每个循环容器,有两个数据流任务,即
Type A files
和Type B files
。 每个根据您的要求,这些数据流任务可以配置为从连接管理器读取文件。 但是,我们需要禁用基于正在读取该文件的任务, -
Type A files
,只有当被处理的类型的文件数据流任务应该启用。 - 类似地,
Type B files
仅当正被处理的B型文件数据流任务应该被启用。 - 为了实现这一目标,点击
Type A files
数据流任务,然后按F4带来的属性。 点击上可用的省略号按钮Expression
特性。 - 在属性表达式编辑器,选择
Disable
物业及输入表达式!(@[User::Type] == "A")
- 同样,点击
Type B files
数据流任务,按F4带来的属性。 点击上可用的省略号按钮Expression
特性。 - 在属性表达式编辑器,选择
Disable
物业及输入表达式!(@[User::Type] == "B")
- 这里是仅包含所述列表中的类型的文件的样本Files.txt。 当执行包读取这个文件,你会发现,只有
Type A files
数据流任务。
- 这里是包含在列表中仅B型文件的另一个样品Files.txt。 当执行包读取这个文件,你会发现,只有
Type B files
数据流任务。
- 如果Files.txt同时包含A和类型B的文件,该循环将执行基于正被处理的文件的类型的相应数据流的任务。
配置数据流任务类型A文件
- 让我们假设你的A型的平面文件有三个栏布局类似与逗号分隔值如下所示。 这里的文件数据使用记事本++的所有特殊字符显示。
CR LF
表示该行与回车和换行结束。 此文件存放的路径C:\ f1.txt
- 我们需要一个数据库表中导入数据。 让我们创建一个表名为
dbo.Table_A
在SQL Server数据库中,如下所示。
- 现在,到SSIS包。 下面是配置命名TYPE_A平面文件连接管理器的详细信息。 给一个名字到连接管理器。 你需要在标题行指定的值4跳过文本框。 你的平面文件连接管理器应该是这个样子。
- 现在,连接管理器配置,我们需要配置数据流任务
Type A files
来处理相应的文件。 对数据流任务双击Type A files
。 将里面的任务平面文件源和OLE DB目标。
- 该平面文件源必须配置为从平面文件连接管理器中的文件。
- 数据流任务没有做什么特别的事情。 它简单地读取类型A的平面文件和数据插入到表dbo.Table_A。 现在,我们需要配置OLE DB目标将数据插入到数据库中。 在平面文件的连接管理器和配置表中的列名不相同。 因此,他们必须手动映射。
- 现在,数据流任务配置。 我们必须从Files.txt正在读取的文件路径是否正确传递。 要做到这一点,点击TYPE_A平面文件连接管理器,然后按F4带来的属性。 设置
DelayValidation
属性为True
。 点击Ellipsis
按钮Expressions
属性。
- 在属性表达式生成器,选择
ConnectionString
属性,并将其设置为表达式@[User::FileName]
- 上述配置步骤必须遵循的B类文件。 然而,数据流任务看起来略有不同,因为该文件处理逻辑是不同的。 数据流任务B类文件将是这样的。 因为你必须在B类文件中的两列插入不同的表。 你必须使用多播改造,将创建输入数据的克隆。 您可以使用每个组播输出的通过,从而使不同的变换或目的地。
希望可以帮助你实现你的任务。
我建议您为每个不同类型的文件加载的,你要做的创建SSIS包。 您可以从其他程序执行的包,请看这里: 如何从.NET执行的SSIS包?
鉴于这一信息,你可以写一个快速的程序来执行相关的包:
var jobs = File.ReadLines("C:\\temp\\order.txt")
.Skip(1)
.Select(line => line.Split(','))
.Select(tokens => new { File = tokens[0], Category = tokens[1] });
foreach (var job in jobs)
{
// execute the relevant package for job.Category using job.File
}
我的解决方案看起来像N + 1个的平面文件连接管理器来处理源文件。 CM A将解决跳过第4行的文件格式,B听起来像它只是一个2列文件,等等。最后10cm将被用来分析你所示的命令文件。
现在,你拥有所有这些定义的连接管理器,你可以去处理逻辑。
创建3个变量。 字符串类型2(CurrentPath,CurrentType)。 1是Object类型的,我把它称为记录。
所述第一数据流从使用平面文件源中读取所有的行“CM控制”。 这是你在你的例子提供的数据。
然后,我们将使用Recordset对象在什么是通常被称为切碎源的foreach循环容器。 宾格尔术语“撕碎记录SSIS”和你一定会触及一些描述如何做到这一点的文章。 最终的结果是,在源CM控制文件中的每一行,你会为这些值到CurrentPath,CurrentType变量。
在这个循环容器,创建一个用于控制的中心点控制辐射出来。 我找到一个脚本任务奇妙的作品这一点。 它拖动到画布上,给它一个强名称,以表明它不是用于任何东西,然后创建一个数据流来处理每个处理排列。
魔力来自使用表达式。 党的一切附近在SSIS可以对它们的性质是什么从poseurs专业人士分开设置表达式。 在这里,我们将双击连接到给定的数据流线,改变从“约束”的约束类型为“表达式和约束”,那么你会用的表达是一样的东西@[User::CurrentType] == "A"
这将确保当两个父任务成功,并且条件不错,路径仅服用。
的表达魔第二位将被施加到连接管理器本身。 他们将需要有自己的ConnectionString属性由价值驱动@[User::CurrentFile]
属性。 这将允许的设计时间值C:\filea.txt
但将允许运行值,从控制文件中,要\\network\share\ClientFileA.txt
除非所有的文件具有相同的结构,你会最有可能需要DelayValidation在属性设置为True。 否则,SSIS将失败PreValidation因为所有的“CM A”至“CM N”将被使用CurrentFile可变其可以是或可以不是该文件布局有效的连接字符串。
文章来源: SSIS - How do I load data from text files where the path of files is inside another text file?