2010-05-24 123 views
2

我們從供應商處收到每晚約10個製表符分隔的平面文件(不帶列標題)的數據導出。另外,供應商爲我們提供了數據庫表的SQL腳本,以便我們可以將文件導入到我們的系統中。SSIS - 我可以從數據庫獲取平面文件源的列架構嗎?

不幸的是,供應商最近更改了平面文件的模式。每個文件有150列以上,並且必須通過數據庫模式並在SSIS中的平面文件數據源上調整列類型非常耗時,更不用說皇室的痛苦了。

因爲我知道數據庫模式中的文件數據佈局,有沒有什麼辦法可以將它動態地拉入到平面文件源來正確設置列?還是我堅持手動設置一切?

回答

1

你不能通過BIDS(男孩,這將是很好),但你一定可以通過對象模型來做到這一點。我構建了一個讀取Focus主文件(描述固定寬度的平面文本佈局)並使用模板包的程序,然後更新連接管理器以反映列布局(我將其讀入我自己的數據結構中)。解析SQL可能有點困難,但這肯定是半自動化的。

請注意,如果SQL具有像int這樣的本機類型,則有人必須告訴您,否則如果使用固定寬度的列,您將必須弄清楚文本文件中int的寬度。在這種情況下,您的生活可能會更容易在CSV中。

我的完整程序還將派生列轉換爲修剪空格並執行一些其他操作 - 生成的包然後被清理並手工測試。

下面是一些示例代碼(MF是我的主文件objectmodel,該代碼加載模板包,增加了一個連接管理器,把所有的字段):

 Application App = new Microsoft.SqlServer.Dts.Runtime.Application(); 
     p = App.LoadPackage(TemplatePackage, null); 

     ConnectionManager cm = p.Connections.Add("FLATFILE"); 
     cm.Properties["Name"].SetValue(cm, mf.SSISConnectionManagerName); 
     cm.Properties["ConnectionString"].SetValue(cm, FlatFilePath); 
     cm.Properties["Format"].SetValue(cm, "FixedWidth"); 
     cm.Properties["RowDelimiter"].SetValue(cm, "\r\n"); 
     cm.Properties["HeaderRowDelimiter"].SetValue(cm, "\r\n"); 
     cm.Properties["CodePage"].SetValue(cm, 1252); 
     cm.Properties["ConnectionString"].SetExpression(cm, "@[User::FilePath] + \"\\\\\" + @[User::FileName]"); 

     RWrap.IDTSConnectionManagerFlatFile90 con = cm.InnerObject as RWrap.IDTSConnectionManagerFlatFile90; 

     List<FocusField> flds = mf.Fields(); 
     foreach (FocusField fld in flds) 
     { 
      RWrap.IDTSConnectionManagerFlatFileColumn90 Col = con.Columns.Add(); 
      (Col as RWrap.IDTSName90).Name = fld.FieldName; 
      Col.ColumnType = "FixedWidth"; 
      Col.ColumnDelimiter = ""; 

      Col.DataType = RWrap.DataType.DT_STR; 
      Col.ColumnWidth = fld.SSISColumnWidth; 
      Col.MaximumWidth = fld.SSISColumnWidth; 
     } 

     RWrap.IDTSConnectionManagerFlatFileColumn90 EolCol = con.Columns.Add(); 
     (EolCol as RWrap.IDTSName90).Name = "CRLF"; 
     EolCol.ColumnType = "FixedWidth"; 
     EolCol.ColumnDelimiter = ""; 
     EolCol.DataType = RWrap.DataType.DT_STR; 
     EolCol.ColumnWidth = 2; 
     EolCol.MaximumWidth = 2;