2009-06-15 68 views
2

有趣的是,我們正在評估用於預處理語句數據(例如公用事業賬單,銀行對帳單)的ETL工具進行打印。SSIS交易數據(不同記錄類型,一個文件)

某些數據通過單個平面文件來處理,具有不同的記錄類型。

例如以「01」作爲第一個字段的記錄類型將是地址數據。這將有名稱和地址字段。具有「02」的記錄類型將是彙總數據,包括餘額和總計。記錄類型「03」將成爲該報表中的一個行項目。

每個語句將有一個01和02記錄和多個03記錄。我可以預先解析文件並將其拆分爲3個文件以加載到表格中,但這並不理想。

我們拿這個文件做一些操作(例如在地址記錄中添加更多的字段,也許做一些總計/驗證),然後以相同的格式發送文件(但是與額外的領域添加)到我們的印刷組合程序。

你會如何在SSIS中做到這一點?

回答

0

這是可能的,你將不得不編寫自定義邏輯。我曾經用DTS做過一次。 如果文件被分隔,SSIS將正確地導入字段。您可以編寫檢查記錄類型字段的腳本,然後根據記錄類型分支到不同的插入。如果文件的記錄沒有分隔,但每種類型都有自己的固定寬度,這會變得更加複雜,因爲您必須解析並拆分每個導入的行,並在腳本中硬編碼記錄類型和寬度。

+0

無需在SSIS編寫自定義腳本。條件拆分是一個簡單的if-then進程,只需要邏輯,不需要腳本。 – Eric 2009-06-15 02:31:45

+0

固定寬度文件如何?你可以在數據中鍵入某個位置,而不是列名? – cdonner 2009-06-15 02:36:36

-1

有幾個方法可以做到這一點,但我想一個最簡單的理解將是源任務後添加一個條件分割,然後將其推過一堆數據轉換任務來獲得正確的格式數據。

確保您的源設置了正確的數據類型,所以沒有任何東西經過(例如,所有字符串)。然後只需檢查該條件分割中的「記錄類型」字段,將其發送到右分支。

+0

使用源數據的傳統方式將不起作用,因爲源只能處理一個佈局。看凱德的答案。 – Sam 2010-02-02 17:34:22

5

的大問題,在SSIS變種的記錄是,你沒有得到任何的連接管理器的佈局幫助的好處,因爲連接管理器只能處理一個單一的佈局。

因此,通常情況下,您最終會得到一個帶有兩列的CRLF終止平面文件:recordtype和recorddata。然後,將條件分割放入並在不同路徑上解析每種類型的行。解析將不得不分割剩餘的記錄數據,並將其放入列中並按正常方式轉換,或者使用派生列轉換或腳本轉換以及潛在的轉換轉換。

如果你有很多的包做,我會認真考慮寫其生產已經轉換到你的目的地類型3個輸出的自定義組件。

3

回答了我自己的問題 - 請參閱下面的腳本。 AcctNum來自平面文件源的派生列,並且將爲02記錄類型正確填充,並將其保存在本地靜態變量中,並將其放回到不包含acct編號的其他記錄類型的行中。使用Microsoft Visual C#2008編寫腳本 * ScriptMain是腳本的入口點類。*/

using System; using System.Data; using Microsoft.SqlServer.Dts.Pipeline.Wrapper; using Microsoft.SqlServer.Dts.Runtime.Wrapper;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute] 公共類ScriptMain:UserComponent { 靜態字符串賬戶號碼= NULL;

public override void PreExecute() 
{ 
    base.PreExecute(); 
    /* 
     Add your code here for preprocessing or remove if not needed 
    */ 
} 

public override void PostExecute() 
{ 
    base.PostExecute(); 
    /* 
     Add your code here for postprocessing or remove if not needed 
     You can set read/write variables here, for example: 
     Variables.MyIntVar = 100 
    */ 
} 

public override void Input0_ProcessInputRow(Input0Buffer Row) 
{ 
    if (Row.RecordType == "02") 
     AccountNumber = Row.AcctNum; // Store incomming Account Number into local script variable 
    else if (Row.RecordType == "06" || Row.RecordType == "07" || Row.RecordType == "08" || 
      Row.RecordType == "09" || Row.RecordType == "10") 
     Row.AcctNum = AccountNumber; // Put Stored Account Number on this row. 
} 

}