如何加载包含有时包含换行符的列的管道(|)分隔文本文件?

时间:2017-10-16 22:09:10

标签: vb.net ssis delimited-text

我已经构建了一个SSIS包,它将几个分隔的文本文件加载到SQL数据库中。其中一个文件通常包含行空间,这打破了设置平面文件源和映射到ado.net目标的标准数据流任务,因为它认为当它到达换行符时它在新行上。发送文件的供应商不希望在没有任何编辑的情况下发送文件,并且此时无法执行XML。有没有什么办法解决这一问题?我正在考虑编写一个小的vb.net程序来纠正文件,以便它们可以在SSIS包中工作,但不知道如何编写该逻辑。该文件有5列,前2个是大整数,并且总是包含一些长整数ID,然后有一个小的文本列,只包含一个短字,然后是一个日期,然后是一个导致问题的长注释字段。注释字段有时是空白的(可以),问题是具有换行符的行。我从来不知道评论中有多少个换行符,有些没有换行符,有些可以有多个,甚至连续多个换行符,所以想知道这是否可行。

5787626 | 6547599 | Approved | 1/10/2017 |申请人要求免除费用豁免 5443221 | 7742812 |活动| 2013年11月5日| 3430962 | 7643957 |重新预定| 5/25/2016 |经修订的条款和条件被拒绝 申请人有30天提交延期文件。 34433624 | 7673715 |拒绝| 2017年1月24日| 34113575 | 7653748 |活动| 1/8/2014 |已授予新条款。

示例文件格式。

Sample File Format

1 个答案:

答案 0 :(得分:0)

只要有逻辑可以编程/预测,就有可能。

我会使用脚本组件作为源,这意味着您在处理文件之前不需要重写文件。它还提供了很大的灵活性,例如,您可以在迭代文件中的多行时将值存储在变量中等。

我最近发布了另一个答案,提供了很多关于如何解决这个问题的详细信息:SSIS import a Flat File to SQL with the first row as header and last row as a total

将值保存在变量中直到准备好写入行的示例: -

对于这个例子,我写了三个列,ID1,ID2和Comments。该文件如下所示:

1|2|Comment1
Comment2
4|5|Comment3
Comment4
Comment5
6|7|Comment6

脚本组件包含以下方法。

public override void CreateNewOutputRows()
{
    System.IO.StreamReader reader = null;

    try
    {
        bool readFirstLine = false;
        int id1 = 0;
        int id2 = 0;
        string comments = null;

        reader = new System.IO.StreamReader(Variables.FilePath); // this refers to a package variable that contains the file path

        while (!reader.EndOfStream)
        {
            string line = reader.ReadLine();

            if (line.Contains("|"))
            {
                if (readFirstLine)
                {
                    Output0Buffer.AddRow();

                    Output0Buffer.ID1 = id1;
                    Output0Buffer.ID2 = id2;
                    Output0Buffer.Comments = comments;
                }
                else
                {
                    readFirstLine = true;
                }

                string[] fields = line.Split('|');

                id1 = Convert.ToInt32(fields[0]);
                id2 = Convert.ToInt32(fields[1]);
                comments = fields[2];
            }
            else
            {
                comments += " " + line;
            }

            if (reader.EndOfStream)
            {
                Output0Buffer.AddRow();

                Output0Buffer.ID1 = id1;
                Output0Buffer.ID2 = id2;
                Output0Buffer.Comments = comments;
            }
        }
    }
    catch
    {
        if (reader != null)
        {
            reader.Close();
            reader.Dispose();
        }

        throw;
    }
}

结果集是:

ID1    ID2    Comments
===    ===    ========
1      2      Comment1 Comment2
4      5      Comment3 Comment4 Comment5
6      7      Comment6