為SSIS編寫簡單的同步轉換組件

來源:互聯網
上載者:User

上一篇講到了同步轉換和非同步轉換的概念。通常情況下,大部分轉換都是同步的,即收到一行就處理一行。(注意,這樣說可能不是很準確,實際上即便是同步機制,資料流也會適當的進行緩衝的,只不過這種緩衝對使用者數透明的,使用者可以理解為收到一行就處理一行)

同步轉換組件可以很簡單,也可以很複雜。這取決於你的設計邏輯。

這一篇我還是用一個簡單的例子來講解,旨在讓大家瞭解同步轉換組件的設計流程。

需求:我們這個組件很簡單,就是將輸入列中的文本列的所有字母全部轉換為大寫。

 

1. 準備一個類型

    [DtsPipelineComponent(







ComponentType=ComponentType.Transform,







Description="這是我的一個自訂資料轉換"






,







DisplayName="大寫轉換"






)]







public






class






MyTransfomation:PipelineComponent







{















}

這個類型是我們上次準備好的,但沒有做實現。【注意】我把DisplayName改成了“大寫轉換”

如果你是從頭開始做,那麼請注意,添加以下的引用和using語句

 

2. 實現代碼

代碼將由幾個部分組成

首先仍然是 ProvideComponentProperties方法,這個方法準備一些中繼資料。一般都是定義輸入和輸出的屬性。該方法的佔位代碼如下

        public






override






void






ProvideComponentProperties()







{







base






.ProvideComponentProperties();







}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

我們對其加以修改。我們需要知道的一個基礎知識就是:任何一個轉換,即便不做任何事情,它也自動具有一個預設的輸入和輸出。

我們在這個代碼裡面給預設的輸入和輸出做一個重新命名。這樣做的目的是讓它們更加形象

        /// <summary>














/// 這個方法提供組件必須的一些屬性。














/// 這裡主要給預設的輸入和輸出重新命名,讓它更加形象














/// </summary>














public






override






void






ProvideComponentProperties()







{







base






.ProvideComponentProperties();







ComponentMetaData.InputCollection[0].Name = "大寫轉換輸入"






;







ComponentMetaData.OutputCollection[0].Name = "大寫轉換輸出"






;







//ComponentMetaData.OutputCollection[1].SynchronousInputID = ComponentMetaData.InputCollection[0].ID;














//如果調用了base.ProvideComponentProperties,則可以省略這句代碼














}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

第二步:我們重寫PreExecute方法,這個方法為執行做準備。我們這裡的需求比較簡單,就是檢查所有最終確定的輸入列,如果他們的類型是字元型(不管是STR還是WSTR),我們就對它們做一個記號

 

        List<int






> _columns = new






List<int






>();//這個集合來儲存需要處理的列的索引號






















/// <summary>














/// 這個方法是ProcessInput之前的準備工作。














/// 我們檢測所有輸入列中類型為字元型的,並將它的索引號記錄起來














/// 為了讓ProcessInput能使用到這個資訊,我們定義一個公用變數














/// </summary>














public






override






void






PreExecute()







{







IDTSInput90 input = ComponentMetaData.InputCollection[0];







IDTSInputColumnCollection90 columns = input.InputColumnCollection;















foreach






(IDTSInputColumn90 item in






columns)







{







if






(item.DataType == DataType.DT_WSTR || item.DataType == DataType.DT_STR)







{







_columns.Add(BufferManager.FindColumnByLineageID(input.Buffer, item.LineageID));







}







}







}
 
第三步:我們重寫ProcessInput方法。這個方法會被資料流程工作多次調用。我們就是不斷地進行處理,直到資料來源不再能提供資料為止。
        public






override






void






ProcessInput(int






inputID, PipelineBuffer buffer)







{







while






(buffer.NextRow())//從這句話可以理解,其實雖然說是同步,但也可能是緩衝了幾行後才處理,而不一定是一行處理一次







{







foreach






(int






index in






_columns)







{







string






str = buffer.GetString(index);







buffer.SetString(index, str.ToUpper());







}







}







}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

我們這裡只是對輸入的buffer進行處理。注意,這裡很有意思的是,我們其實很簡單的,先把buffer中某個列的值讀出來,然後將其轉回大寫之後寫回去即可。

 

3. 重新編譯項目,部署。在BI Studio中進行測試

我們只需要勾選上有關的輸入列即可。其他不需要任何的設定

現在就可以執行任務了。如果不出意外,任務能夠成功執行,如所示

我們最後開啟產生的那個文字檔進行驗證

我們看到,第一列和第三列的文本全部被處理成了大寫。

我們也可以在資料流中添加“查看器”,很清楚的看到從“檔案夾資料來源”到“大寫轉換”這個管道中,字元是小寫

而在“大寫轉換”到“一般檔案目標”這個管道中,字元就被轉變為大寫了

 

補充:

該轉換組件已經可以工作了。但我們還是可以添加下面的一些功能(例如驗證),以便讓它更加完整

        public






override






DTSValidationStatus Validate()







{







//驗證組件,至少要有一個輸入列














IDTSInput90 input = ComponentMetaData.InputCollection[0];







if






(input.InputColumnCollection.Count > 0)







return






DTSValidationStatus.VS_ISVALID;















ComponentMetaData.FireWarning(0,







ComponentMetaData.Name,







"至少應該選擇一個輸入列"






,







string






.Empty,







0);







return






DTSValidationStatus.VS_ISBROKEN;







}















public






override






void






DeleteInput(int






inputID)







{







throw






new






Exception("不能刪除輸入"






);







}















public






override






IDTSCustomProperty90 SetInputProperty(int






inputID,







string






propertyName, object






propertyValue)







{







throw






new






Exception("不能修改輸入"






);







}

這樣的話,如果使用者沒有選擇列,則會出現下面的錯誤

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.