我已经构建了一个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 |已授予新条款。
示例文件格式。
答案 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