2010-07-06 66 views
1

是SSIS自定义组件的新手。刚刚开始编写一个组件,其中输入行数永远不会与输出行数相同。 foreach输入行它会进行一些验证并生成需要映射到输出缓冲区的n行。创建SSIS自定义数据流组件+ SSIS 2008

所以在设计时验证编码后,一切都很好。

我运行时的代码如下:

public override void PreExecute() 
    { 
     IDTSInput100 input = ComponentMetaData.InputCollection[0]; 
     inputBufferColumnIndex = new int[input.InputColumnCollection.Count]; 

     for (int x = 0; x < input.InputColumnCollection.Count; x++) 
     { 
      IDTSInputColumn100 column = input.InputColumnCollection[x]; 
      inputBufferColumnIndex[x] = BufferManager.FindColumnByLineageID (input.Buffer, column.LineageID); 
     } 

     IDTSOutput100 output = ComponentMetaData.OutputCollection[0]; 
     outputBufferColumnIndex = new int[output.OutputColumnCollection.Count]; 

     for (int x = 0; x < output.OutputColumnCollection.Count; x++) 
     { 
      IDTSOutputColumn100 outcol = output.OutputColumnCollection[x]; 
      outputBufferColumnIndex[x] = BufferManager.FindColumnByLineageID(input.Buffer, outcol.LineageID); 
     } 

    } 


    public override void ProcessInput(int inputID, PipelineBuffer buffer) 
    { 
     if(!buffer.EndOfRowset) 
     { 
      while (buffer.NextRow()) 
      { 
       var rec = new Record 
           { 
            Source = buffer[0].ToString(), 
            Nk = buffer[1].ToString(), 
            Guid = new Guid(buffer[2].ToString()), 
            FromDate = Convert.ToDateTime(buffer[3].ToString()), 
            ToDate = Convert.ToDateTime(buffer[4].ToString()) 
           }; 
       sourceRecords.Add(rec); 
      } 
      ProcessArray(sourceRecords,buffer); 
     } 
    } 
    public void ProcessArray(List<Record> records, PipelineBuffer buffer) 
    { 
     //Get Distinct NKs from the source Records 
     List<string> nKs = (from c in records select c.Nk).Distinct().ToList(); 


     foreach (var nk in nKs) 
     { 
      //Get all the record for particular NK 
      List<Record> filteredRecords = (from c in sourceRecords where c.Nk == nk select c) 
               .OrderBy(c => c.Source) 
               .ThenBy(c => c.FromDate) 
               .ThenBy(c => c.ToDate).ToList(); 

      foreach (var filteredRecord in filteredRecords) 
      { 
       _start = filteredRecord.FromDate; 
       _end = filteredRecord.ToDate; 
       while (filteredRecord.WriteComplete == false) 
       { 
        foreach (var record in filteredRecords) 
        { 
         if (record.FromDate > _start && record.FromDate < _end) _end = record.ToDate; 
         if (record.ToDate < _end && record.ToDate > _start) _end = record.ToDate; 
        } 

        //Output0Buffer.AddRow(); 
        //Output0Buffer.outSource = filteredRecord.Source; 
        //Output0Buffer.outNK = filteredRecord.Nk; 
        //Output0Buffer.outRecid = filteredRecord.Guid; 
        //Output0Buffer.outFromDate = _start; 
        //Output0Buffer.outToDate = _end; 
        buffer.SetString(5,filteredRecord.Source); 
        buffer.SetString(6,filteredRecord.Nk); 
        buffer.SetGuid(7,filteredRecord.Guid); 
        buffer.SetDateTime(8,filteredRecord.FromDate); 
        buffer.SetDateTime(9,filteredRecord.ToDate); 

        _start = _end; 
        _end = filteredRecord.ToDate; 

        if (_start == _end) filteredRecord.WriteComplete = true; 
       } 
      } 
     } 
    } 
} 
public class Record 
{ 
    public Guid Guid { get; set; } 
    public string Nk { get; set; } 
    public string Source { get; set; } 
    public DateTime FromDate { get; set; } 
    public DateTime ToDate { get; set; } 
    public bool WriteComplete { get; set; } 
} 

在我ProcessArray方法我试图填充输出缓冲区。我甚至不确定这可以做到。

任何指导将不胜感激。

谢谢

回答

0

是这种类型的转换可以完成,它被称为异步转换。你的代码对我来说很好。从您的问题中不清楚您是否遇到特定问题。

您可能想尝试创建一个异步脚本组件转换,因此您不必对所有SSIS管道进行摸索。

更多的信息在这里: http://msdn.microsoft.com/en-us/library/ms136133.aspx

http://msdn.microsoft.com/en-us/library/ms135931.aspx

+0

谢谢杰森,通过这些链接,并修复了我的组件。 – Sreedhar 2010-07-09 04:11:49

0

我不知道我理解你想要达到的,不过貌似你试图把所有的数据进行排序,然后依次处理排序名单。请注意,您的ProcessInput方法被多次调用,每个都有一个新的缓冲区。对接收缓冲区进行的任何排序仅适用于此特定缓冲区 - 数据不会全局排序,因此您的结果可能因缓冲区边界而异。

对于特定场景,这可以吗?如果没有,请使用排序变换为您排序所有数据,在排序后添加变换,并逐行处理数据 - 它已经排序。所以只需逐行读取,然后在读取后修改当前行行 - 这是buffer.SetString的用途。

另外,不要硬编码列指针,像buffer.SetString(5,...) - 数字可能会改变,最好是在PreExecute中获取并保存列索引,然后使用类似 缓冲区。 SetString(nkColumnIndex,nkColumnValue);