微軟BI 之SSIS 系列 - 通過 ROW_NUMBER 或 Script Component 為數據流輸出添加行號的方法


開篇介紹

上午在天善回答看到這個問題 - SSIS 導出數據文件,能否在第一列增加一個行號,很快就幫助解決了,方法就是在 SQL 查詢的時候加一個 ROW_NUMBER() 就可以了。

后來想起在兩年前我的第一個 BI 項目上也有類似的文件輸出需求,但是比這個要復雜的多,因為涉及到多個輸入列的邏輯判斷和計算問題,比如還有一些 XML 格式的數據。這些邏輯不能直接在 SQL 查詢時直接實現,比如還要做 XML 格式驗證,字符串匹配查找,還有其它的比較復雜的邏輯。所以就選擇了另外一種方式 - 在數據源輸入和文件輸出組件之間加了一個 Script Component 組件,利用它程序化處理添加了必要的輸出列供下游使用,當然邏輯比較復雜在 Script Component 中寫了不少代碼還有異常記錄輸出等。

雖然沒有必要使用 Script Component 來解決這個問題,但是還是可以通過這個小例子簡單介紹一下 Script Component,多了解一種方法,在項目需要的時候就多一種選擇。

使用 Script Component 為數據流輸出添加行號

數據源可以隨便選用一張表來進行測試輸出。

數據源向下的輸出列 -

拖放一個排序控件,如果希望輸出的格式按某列排序的話,可以選擇一個列來排序,這里使用 FullName 進行排序。

拖放一個 Script Component,這里要選擇 Transfomation 轉換,意味着在輸入源和輸出目的地之間進行中間轉換的組件。

如果以后在 Script 中有比較復雜的邏輯運算需要使用到輸入源的某些列的話,可以在這里選中它。

最重要的就是這里的輸出列了,這個輸出列之前並不存在,是通過 Script Component 創建出來的,后面可以使用到的。

選擇 Script 項並點擊 Edit Script 打開之后就能看到這些代碼,這里面有幾個方法。

  • PreExecute() - 只會被調用一次,在數據流執行到這個控件的時候調用,並且是在所有行處理前調用,可以在這里做一些初始化計算。
  • PostExecute() - 當所有行全部處理完之后調用,可以在這里和 PreExecute() 配合起來記錄處理的時間,時長等等。
/// <summary>
    /// This method is called once, before rows begin to be processed in the data flow.
    ///
    /// You can remove this method if you don't need to do anything here.
    /// </summary>
    public override void PreExecute()
    {
        base.PreExecute();
        /*
         * Add your code here
         */
    }

    /// <summary>
    /// This method is called after all the rows have passed through this component.
    ///
    /// You can delete this method if you don't need to do anything here.
    /// </summary>
    public override void PostExecute()
    {
        base.PostExecute();
        /*
         * Add your code here
         */
    }

    /// <summary>
    /// This method is called once for every row that passes through the component from Input0.
    ///
    /// Example of reading a value from a column in the the row:
    ///  string zipCode = Row.ZipCode
    ///
    /// Example of writing a value to a column in the row:
    ///  Row.ZipCode = zipCode
    /// </summary>
    /// <param name="Row">The row that is currently passing through the component</param>
    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        /*
         * Add your code here
         */
    }

最后的一個方法是我們要使用到的,就是轉換處理。在方法外面定義一個變量,表示行號從 1 開始。方法參數 Row 已經將之前在 Script Component 中引用的 InputColumn 和 創建的 OutputColumn 全部包裝成了屬性,直接可以通過 Input0Buffer Row 來調用。 那么每進來一行數據,這個方法就被調用一次並同時向下輸出一次。也就是說進來一行,處理一行,出去一行。

    int rowNumber = 1;
    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        Row.RowNumber = rowNumber;
        rowNumber = rowNumber + 1;
    }

保存並執行包,開啟一個 Data Viewer 查看一下運行時的數據,就能看到 RowNumber 已經創建好了,下游就可以向文件寫入數據了。

使用 ROW_NUMBER()來實現添加數據流的行號

當然對於這個例子,直接使用 ROW_NUMBER() 最簡單了,維護成本很低。

一步就搞定了同樣的效果。

更多 BI 文章請參看 BI 系列隨筆列表 (SSIS, SSRS, SSAS, MDX, SQL Server) 如果覺得這篇文章看了對您有幫助,請幫助推薦,以方便他人在 BIWORK 博客推薦欄中快速看到這些文章。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM