我有一个文本文件,其中包含要加载到数据库中的文件列表。
该列表包含两列:
FilePath,Type
c:\f1.txt,A
c:\f2.txt,B
c:\f3.txt,B
我想提供此文件作为SSIS的来源。然后我希望它逐行完成。对于每一行,我希望它读取FilePath列中的文件并检查Type。
如果type是A,那么我希望它忽略位于当前行的FilePath列的文件的前4行,然后将该文件中的其余数据加载到表中。 如果type是B,那么我希望它打开文件并将文件的第一列复制到表1中,将第二列复制到表2中以获取所有行。
如果有人可以请我提供我需要遵循的高级别步骤列表,我将非常感激。
感谢任何帮助。
答案 0 :(得分:4)
以下是在SSIS中执行此操作的一种方法。以下步骤适用于 SSIS 2008 R2 。
FileName
,FilesToRead
和Type
。 FilesToRead变量将保存文件列表及其类型信息。我们将有一个循环,它将遍历每个记录,并在每次循环时将信息存储在 FileName 和 Type 变量中。
SQLServer
。FileName
和Type
的列。将其命名为 Files
。Type_A
。在此平面文件连接管理器中,在文本框Header rows to skip
中输入值4,以便始终跳过前四行。Type_B
。
Files
读取所有文件,然后放置Recordset Destination
。在记录集目标中配置变量FilesToRead
。您的第一个数据流任务如下所示。
FilesToRead
中的记录集。由于记录集包含两列,每次循环记录时,变量FileName
和Type
将被赋予当前记录的值。
Type A files
和Type B files
。您可以根据需要配置每个数据流任务,以从连接管理器中读取文件。但是,我们需要根据正在读取的文件禁用任务。Type A files
数据流任务。Type B files
数据流任务。Type A files
数据流任务,然后按F4以显示属性。单击Expression
属性上的省略号按钮。 Disable
属性,然后输入表达式!(@[User::Type] == "A")
Type B files
数据流任务,然后按F4以显示属性。单击Expression
属性上的省略号按钮。 Disable
属性,然后输入表达式!(@[User::Type] == "B")
Type A files
数据流任务。
Type B files
数据流任务。
CR LF
表示这些行以回车符和换行符结尾。该文件存储在路径C:\ f1.txt
dbo.Table_A
的表,如下所示。
Type A files
来处理相应的文件。双击数据流任务Type A files
。在任务中放置一个平面文件源和OLE DB目标。
DelayValidation
属性设置为True
。点击Ellipsis
媒体资源上的Expressions
按钮。
ConnectionString
属性并将其设置为表达式@[User::FileName]
希望能帮助您完成任务。
答案 1 :(得分:1)
我建议您为要执行的每种不同类型的文件加载创建一个SSIS包。您可以从其他程序执行这些程序包,请参阅此处:How to execute an SSIS package from .NET?
根据这些信息,您可以编写一个快速程序来执行相关的包:
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
}
答案 2 :(得分:1)
我的解决方案看起来像N + 1平面文件连接管理器来处理源文件。 CM A将解决跳过前4行文件格式,B听起来像是一个2列文件等。最后一个CM将用于解析您已经说明的命令文件。
现在已经定义了所有这些连接管理器,您可以进行处理逻辑。
创建3个变量。 2类型字符串(CurrentPath,CurrentType)。 1是Object类型,我称之为Recordset。
第一个数据流使用“CM Control”从平面文件源读取所有行。这是您在示例中提供的数据。
然后,我们将使用该Recordset对象作为ForEach循环容器的源,通常称为碎化。 Bingle术语“Shred recordset ssis”,你必然要写一些描述如何做的文章。最终结果是,对于源CM控制文件中的每一行,您将这些值分配给CurrentPath,CurrentType变量。
在Loop容器内,创建一个控制中心点以控制辐射。我发现脚本任务对此非常有效。将它拖到画布上,给它一个强名称,表示它没有用于任何东西,然后创建一个数据流来处理每个处理排列。
魔术来自于使用表达式。在SSIS的所有东西附近的Dang可以在他们的属性上设置表达,这是专业人士与poseurs的区别。在这里,我们将双击连接到给定数据流的行并将约束类型从“约束”更改为“表达式和约束”然后您将使用的表达式类似于@[User::CurrentType] == "A"
这将确保路径是仅在父任务成功且条件为真时才采用。
表达魔术的第二位将应用于连接管理器本身。他们需要使用@[User::CurrentFile]
属性的值驱动其ConnectionString属性。这将允许设计时值为C:\filea.txt
,但允许来自控制文件的运行时值为\\network\share\ClientFileA.txt
除非所有文件具有相同的结构,否则您很可能需要设置属性中的DelayValidation为True。否则,SSIS将失败PreValidation,因为所有“CM A”到“CM N”将使用该CurrentFile变量,该变量可能是也可能不是该文件布局的有效连接字符串。