2017-10-16 46 views
0

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

5787626 | 6547599 |核准| 1/10/2017 |申请费豁免核准批准 5443221 | 7742812 |活跃| 11/5/2013 | 3430962 | 7643957 |重新计划| 5/25/2016 |修订的条款和条件被驳回 申请人有30天提交延期的文书工作。 34433624 | 7673715 |拒绝| 1/24/2017 | 34113575 | 7653748 |活动| 1/8/2014 |新条款已被授予。

示例文件格式。

Sample File Format

+0

我已经做了类似的事情。从我的方法中获取指导​​。我创建了一个包含30列的临时表(我的管道分隔列固定为MAX 30)。现在阅读管道隔离的列并将它们写入txt文件。然后再次从文本中读取并将它们放入暂存表中。写入后删除txt文件。希望这是有道理的? –

+0

我不明白,如果我将文件加载到临时表中,那么我剩下的临时表的数据列中没有任何意义。例如,这将使我在诸如“申请人有30天”之类的文本中只能包含大整数值的列。 –

+0

你在找什么样的输出?我想我误解了你的输出要求。 –

回答

0

只要有可以编程/预测逻辑,这将是可能的。

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

我最近发布的另一种答案是对如何去这个问题很多的细节:SSIS import a Flat File to SQL with the first row as header and last row as a total

的变量持有的值,直到该行已准备好一个例子写成: -

在这个例子中我写三列,ID1,ID2和评论。该文件是这样的:

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 
+0

由于字段中数字/字符的长度不是固定长度,因此我无法使用子字符串,甚至无法将(|)字符拆分为数组,因为通常最后的注释字段为空,并且它读取在评论栏中下一行的第一行。 –

+0

你可以在你的逻辑中做一些事情,如果一行不包含管道,只需将该字符串添加到前一行的注释字段的末尾?您可以为每个字段使用变量,并且只有在知道完成后才创建行,即读取包含管道的新行。 –

+0

是的,这听起来像一个好主意,但不知道该怎么做,你回去并追加到前一行。 –

相关问题