好吧,正如主题所说,我面临着将数据导出到SQL Server的问题 我有一个分号分隔文件,但是当我在文本中找到分号时我也会出现,例如:
ID;DESCRIPTION;VALUE
1;TEXT1;35
2;TEXT;2;45
3;TE;XT3;50
因为你可以看到我有一些我想删除的垃圾,因为这会改变列。
我有一些想法,比如制作一个标准的分号,在这种情况下,它将按行分为2个分号并删除多余的分号。
在我的情况下,这总是发生在1列,特别是地址列和补充,所以我确切知道列的编号是什么。
我无法询问处理此文件的人,因为系统是一个旧系统,他们不能像双引号那样放置限定符或只是更改分隔符。
我知道我可以通过脚本任务完成这项任务,但我对编程知之甚少,所以我试图寻找另一种方式。
我想再次说明这个问题发生在源文件上,所以当我配置平面文件连接时,它已经移动了列,所以我不能像派生列或其他任何东西那样进行任何处理。在将其加载到SSIS之前,我必须对文件本身进行更改。
我一直在寻找任何类型的论坛上的日子,我没有看到任何类似的问题和解决方案来解决这个问题,因为大多数人的示例文件已经有资格或类似的东西,如果你能帮助我,我真的很感激!
答案 0 :(得分:0)
您提到您几乎没有编程知识,但脚本只是可以处理未包含的字段中的分隔符的解决方案。幸运的是,只有一个问题字段,因为除非您有其他规则来确定实际字段的开始和结束位置,否则无法解析模糊分隔符。
只要您确定只有一个带嵌入分隔符的字段,一个方法就是数据流源脚本组件。以下是创建一个的步骤:
将脚本组件添加到数据流,并选择类型为
将平面文件连接管理器添加到脚本属性Connection Managers集合
在脚本属性组件输入和输出
编辑脚本源并使用下面的版本代码替换模板'CreateOutputRows()'方法代码。
请参阅脚本中的注释,指出实际文件需要自定义的位置。此版本将与3个字段的示例文件一起使用,第二个字段具有嵌入的分隔符。
public override void CreateNewOutputRows()
{
const char FIELD_DEMIMITER = ';';
////*** change this to the zero-based index of the problem field
const int BAD_FIELD_INDEX = 1;
////*** change this to the connection added to script componenent connection manager
var filePath = this.Connections.FlatFileSource.ConnectionString;
string record = "";
using (var inputFile = new System.IO.StreamReader(filePath))
{
record = inputFile.ReadLine();
if(record != null)
{
//count header record fields to get expected field count for data records
var headerFieldCount = record.Split(FIELD_DEMIMITER).Length;
while (record != null)
{
record = inputFile.ReadLine();
if(record == null)
{
break; //end of file
}
var fields = record.Split(FIELD_DEMIMITER);
var extraFieldCount = fields.Length - headerFieldCount;
if (extraFieldCount < 0)
{
//raise an error if fewer fields that we expect
throw new DataException(string.Format("Invalid record. {0} fields read, {1} fields in header.", fields.Length, headerFieldCount));
}
if (extraFieldCount > 0)
{
var newFields = new string[headerFieldCount];
//copy preceding good fields
for (var i = 0; i < BAD_FIELD_INDEX; ++i)
{
newFields[i] = fields[i];
}
//combine segments of bad field into single field
var sourceFieldIndex = BAD_FIELD_INDEX;
var combinedField = new System.Text.StringBuilder();
while (sourceFieldIndex <= extraFieldCount + BAD_FIELD_INDEX)
{
combinedField.Append(fields[sourceFieldIndex]);
if(sourceFieldIndex < extraFieldCount + BAD_FIELD_INDEX)
{
combinedField.Append(FIELD_DEMIMITER); //add delimiter back to field value
}
++sourceFieldIndex;
}
newFields[BAD_FIELD_INDEX] = combinedField.ToString();
//copy subsquent good fields
var targetFieldIndex = BAD_FIELD_INDEX + 1;
while (sourceFieldIndex < fields.Length)
{
newFields[targetFieldIndex] = fields[sourceFieldIndex];
++sourceFieldIndex;
++targetFieldIndex;
}
fields = newFields;
}
//create output record and copy fields
this.Output0Buffer.AddRow();
//*** change the code below to map source fields to the columns defined as script component output
Output0Buffer.ID = fields[0];
Output0Buffer.DESCRIPTION = fields[1];
Output0Buffer.VALUE = fields[2];
}
}
}
this.Output0Buffer.SetEndOfRowset();
}
答案 1 :(得分:0)
您可以做的另一件事是将文本文件导入单个列(varchar(max))
登台表,然后使用TSQL解析记录并将它们导入到最终目标表。