2010-11-25 78 views
14

SSIS在處理平面文件方面做了兩件事情,這些事情特別令人沮喪,似乎應該有一種解決方法,但我無法弄清楚。如果您定義了一個包含10列的平面文件,則使用CRLF作爲行標記的末尾進行分隔的製表符適用於每行只有10列的文件。 2.痛苦的情況是這些:帶有可變列號的SSIS平面文件

  1. 如果有人提供文件與第11欄的任意位置,這將是很好,如果SSIS簡單地忽略它,因爲你還沒有定義它。它應該只讀取你已經定義的10個列,然後跳到行標記的末尾,但是將其他數據與第10列中的數據連接起來並將所有數據連接到第10列。真的很沒用。我意識到發生這種情況是因爲第10列的分隔符不像其他所有的標籤一樣,而是CRLF,因此它只是抓取了CRLF的所有內容,沒有任何內容替代額外的標籤。在我看來,這並不聰明。

  2. 如果有人提供了一個文件,其中僅有9列有事更糟糕。它會暫時忽略它意外發現的CRLF,並填寫下一行開頭的所有缺失列!在這裏,不聰明是輕描淡寫。誰會想要這樣的事情發生?該文件的其餘部分在那個時候是垃圾。

它似乎沒有不合理的有什麼理由在文件寬度的變化(當然只是在行的結尾變化可以reaonably處理(X更少或額外的列),但它看起來這是隻是處理不好,除非我錯過了一些東西

到目前爲止,我們唯一的解決方法是加載一行作爲一個巨型列(column0),然後使用腳本任務動態分割它,但使用了很多分隔符除了它將行寬限制爲4000個字符(一個unicode列的最大寬度)之外,這種方式效果很好,如果你需要導入一個更寬的行(比如有4000個寬列用於文本導入),那麼你需要定義多個列爲abo ve,但是你仍然堅持要求每行有嚴格的列數。

有沒有辦法解決這些限制?

回答

12

Glenn,我感到你的痛苦:) SSIS不能使列動態,因爲它需要存儲每列的元數據,因爲我們正在處理可以包含任何類型數據的平面文件,它不能假定在'列不是最後一列'中的CRLF確實是它應該讀取的數據行的末尾。

與SQL2000中的DTS不同,不能在運行時更改SSIS包的屬性。

你可以做的是創建一個父包,讀取平面文件(腳本任務),並且只讀取平面文件的第一行獲得的列數和列名。這個信息可以存儲在一個變量中。

然後,父包加載子包(腳本任務再次)編程,並更新子包的源連接的元數據。這是您要麼 的位置1.添加/刪除列以匹配平面文件。 2.設置列分隔符爲列,在最後一欄是CRLF - 在數據流任務相匹配的行分隔符 3.重新初始化元數據(ComponentMetadata.ReinitializeMetadata())來源Compoenent的(承認最近源連接中的更改)。 4.保存兒童ssis包。

有關以編程方式修改軟件包的詳細信息只能隨時使用。

然後,您的父包只是執行Child包(執行包任務),並且它會與您的新映射一起執行。