如何跳过 ssis 平面文件源中的坏行

how to skip a bad row in ssis flat file source

我正在将一个 17 列的 CSV 文件读入数据库。 文件偶尔会有 "less then 17-column" 行。 我试图忽略该行,但即使所有列都设置为忽略,我也无法忽略该行并且包失败。

如何忽略那些行?

加载 CSV 并跳过不包含 17 列的行的 C# 解决方案:

使用脚本组件: 在 input/output 屏幕上添加所有具有数据类型的输出。

string fName = @"C:\test.csv" // Full file path: it should reference via variable

string[] lines = System.IO.File.ReadAllLines(fName);

//add a counter
int ctr = 1;

foreach(string line in lines)
{
    string[] cols = line.Split(',');

    if(ctr!=1) //Assumes Header row. elim if 1st row has data
    {
    if(cols.Length == 17)
    {
          //Write out to Output
          Output0Buffer.AddRow();
          Output0Buffer.Col1 = cols[0].ToString(); //You need to cast to data type
          Output0Buffer.Col2 = int.Parse(cols[1]) // example to cast to int
          Output0Buffer.Col3 = DateTime.Parse(cols[2]) // example of datetime
          ... //rest of Columns
    }
    //optional else to handle skipped lines
    //else 
    // write out line somewhere
    }
    ctr++; //increment counter
}

解决方案概述

您可以通过添加一个 Flat File Connection Manager 仅添加一个数据类型为 DT_WSTR 且长度为 4000 的列(假设其名称为 Column0) - 所以所有列都被视为一个大列

  • Dataflow task中,在Flat File Source
  • 之后添加一个Script Component
  • Column0标记为输入列并添加17个输出列
  • Input0_ProcessInputRow方法中用分隔符拆分Column0,然后检查数组的长度是否为=17然后为输出列赋值,否则忽略该行。

详细解决方案

  1. 添加平面文件连接管理器,Select文本文件
  2. 转到高级选项卡,删除除一列以外的所有列
  3. 将 remianing 列的数据类型更改为 DT_WSTR 并且长度 = 4000

  1. 添加数据流任务
  2. 在数据流任务中添加平面文件源、脚本组件和 OLEDB 目标

  1. 在脚本组件中 Select Column0 作为输入列

  1. Add 17 Output Columns(最佳输出列)
  2. OutputBufferSynchronousInput属性改为None

  1. Select 脚本语言 Visual Basic

  1. 在脚本编辑器中编写以下脚本

    Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
    
        If Not Row.Column0_IsNull AndAlso
                Not String.IsNullOrEmpty(Row.Column0.Trim) Then
    
    
            Dim strColumns As String() = Row.Column0.Split(CChar(";"))
    
            If strColumns.Length <> 17 Then Exit Sub
    
    
            Output0Buffer.AddRow()
            Output0Buffer.Column = strColumns(0)
            Output0Buffer.Column1 = strColumns(1)
            Output0Buffer.Column2 = strColumns(2)
            Output0Buffer.Column3 = strColumns(3)
            Output0Buffer.Column4 = strColumns(4)
            Output0Buffer.Column5 = strColumns(5)
            Output0Buffer.Column6 = strColumns(6)
            Output0Buffer.Column7 = strColumns(7)
            Output0Buffer.Column8 = strColumns(8)
            Output0Buffer.Column9 = strColumns(9)
            Output0Buffer.Column10 = strColumns(10)
            Output0Buffer.Column11 = strColumns(11)
            Output0Buffer.Column12 = strColumns(12)
            Output0Buffer.Column13 = strColumns(13)
            Output0Buffer.Column14 = strColumns(14)
            Output0Buffer.Column15 = strColumns(15)
            Output0Buffer.Column16 = strColumns(16)
    
        End If
    
    End Sub
    
  2. 将输出列映射到目标列

这是@SidC 在我的另一个回答中的评论。

这让您可以处理多个文件:

        //set up variables
        string line;
        int ctr = 0;

        string[] files = System.IO.Directory.GetFiles(@"c:/path", "filenames*.txt");
        foreach(string file in files)
        {
            var str = new System.IO.StreamReader(file);
            while((line = str.ReadLine()) != null)
            {
                // Work with line here similar to the other answer
            }
        }