如何跳过 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然后为输出列赋值,否则忽略该行。
详细解决方案
- 添加平面文件连接管理器,Select文本文件
- 转到高级选项卡,删除除一列以外的所有列
- 将 remianing 列的数据类型更改为
DT_WSTR
并且长度 = 4000
- 添加数据流任务
- 在数据流任务中添加平面文件源、脚本组件和 OLEDB 目标
- 在脚本组件中 Select
Column0
作为输入列
- Add 17 Output Columns(最佳输出列)
- 将
OutputBuffer
SynchronousInput
属性改为None
- Select 脚本语言
Visual Basic
在脚本编辑器中编写以下脚本
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
将输出列映射到目标列
这是@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
}
}
我正在将一个 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
之后添加一个 - 将
Column0
标记为输入列并添加17个输出列 - 在
Input0_ProcessInputRow
方法中用分隔符拆分Column0
,然后检查数组的长度是否为=17然后为输出列赋值,否则忽略该行。
Script Component
详细解决方案
- 添加平面文件连接管理器,Select文本文件
- 转到高级选项卡,删除除一列以外的所有列
- 将 remianing 列的数据类型更改为
DT_WSTR
并且长度 =4000
- 添加数据流任务
- 在数据流任务中添加平面文件源、脚本组件和 OLEDB 目标
- 在脚本组件中 Select
Column0
作为输入列
- Add 17 Output Columns(最佳输出列)
- 将
OutputBuffer
SynchronousInput
属性改为None
- Select 脚本语言
Visual Basic
在脚本编辑器中编写以下脚本
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
将输出列映射到目标列
这是@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
}
}