SSIS - 是否存在可处理列顺序可能更改的CSV文件的数据流源组件?

时间:2009-01-28 15:14:57

标签: ssis csv

我们编写了许多SSIS包,使用平面文件源从CSV文件导入数据。

现在看来,在将这些软件包部署到生产环境之后,这些文件的提供者可能会提供文件列顺序发生变化的文件(请勿询问!)。目前,如果发生这种情况,我们的包将失败。

例如,在每行的开头插入一个附加列。在这种情况下,平面文件源继续使用现有的列顺序,这显然会对转换产生不利影响!

EG。使用一个简单的示例,原始文件具有以下内容:

OurReference,Client,Amount
235,MFI,20000.00
236,MS,30000.00

平面文件源的输出是:

OurReference   Client   Amount
235            ClientA  20000.00
236            ClientB  30000.00

随后,传送的文件更改为:

OurReference,ClientReference,Client,Amount
235,A244,ClientA,20000.00
236,B222,ClientB,30000.00

当针对此文件运行现有的未更改的包时,平面文件源的输出为:

OurReference   Client   Amount
235            A244     ClientA,20000.00
236            B222     ClientB,30000.00

理想情况下,我们希望使用能够解决此问题的数据源 - 即根据列名而不是列顺序生成输出。

欢迎任何建议!

3 个答案:

答案 0 :(得分:1)

最佳方法是在SSIS包导入CSV数据之前运行检查。这可能必须是外部脚本/应用程序,因为我不认为您可以在MS Business Intelligence Studio中操作数据。

答案 1 :(得分:1)

不是我知道的。

提前检查问题的可能性是设置两个不同的连接管理器,一个具有单个平行。这个可以读取第一行并判断它是否正常并中止。

如果你想做这项工作,你可以更进一步,让那个扁平的单字段行成为唯一的连接管理器,并使用流中的脚本组件来解析行并分配给你需要的列后来在流程中。

据我所知,没有办法在运行时动态地向流添加列 - 因此需要将所需的所有列添加到脚本任务输出中。是否可以找到它们并从每一行解析它取决于您。不能使用任何“新”(即未预料到的)列。缺少您的列可能会默认或抛出异常。

最后一种可能性是在运行之前使用SSIS对象模型修改包以更改连接管理器 - 甚至可以使用基于输入文件检查的对象模型动态编写整个包。我在C#中使用模板完成了相当多的包生成,然后根据从描述大型机文件的主文件中获取的元数据添加了信息。

答案 2 :(得分:0)

这是一个粗略的方法。我会在最后写下限制。 创建一个平面文件源。将整行放在一列中。 不要检查第一个数据行中的列名称。 创建脚本组件 代码:

public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    string sRow = Row.Column0;

    string sManipulated = string.Empty;
    string temp = string.Empty;

    string[] columns = sRow.Split(',');

    foreach (string column in columns)
    {
       sManipulated = string.Format("{0}{1}", sManipulated, column.PadRight(15, ' '));
    }
    /* Note: For sake of demonstration I am padding to 15 chars.*/

    Row.Column0 = sManipulated; 
}

创建一个平面文件目的地 将Column0映射到Column0

限制:我随意将每个字段填充为15个字符。需要考虑的要点: 1.我们需要每个相同大小的领域吗? 2.如果是,那个大小是多少?

处理这种情况的一般方法是创建一个表来存储文件名,字段和字段大小。 使用文件名动态创建源和目标连接管理器。 使用字段名称和相应的字段大小来确定填充。不确定,如果你需要这么大的灵活性。如果您有任何疑问,请回复。