2010-07-06 65 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);