2016-06-09 57 views
4

我需要使用SSIS將幾千個txt文件放入SQL Server 2012實例中。SSIS 2012 - 條件標頭的位置

問題是,一些txt文件在前兩行中有控制校驗和,而另一些則沒有。

如果一個文件有一個校驗和,它的第一行以「HEADER」開始 - 在這種情況下,我必須跳過前兩行,然後從第3行讀取列標題並從第4行開始加載數據。

如果文件沒有校驗和,列名將存在於行#1中,數據從行#2開始。

現在,我的問題是:處理這種情況的侵入性最小的方法是什麼?我很懶,所以我正在尋找最小的努力與最大的影響。

我的想法到目前爲止:

  1. 檢測校驗的存在與C#腳本組件,構建兩個獨立的流,一個用於每個文件的類型。缺點:兩個幾乎相同的流程(我不是冗餘的粉絲)

  2. 在運行SSIS流程之前先使用PowerShell擺脫文件中的校驗和。缺點:需要重新編寫大量文件(性能受到影響)

  3. 詢問StackOverflow。缺點:可以被StackOverflow社區視爲具有諷刺意味。

任何提示?

+0

也許包括第一列的條件拆分放棄頭和Checksum將爲您工作。 – vercelli

+0

那麼校驗和具有不同的列結構(比實際的列/數據)。我不明白條件分割對此有何幫助。 –

+0

但是,如果你跳過第一行,你將擺脫CHECKSUM,對吧?然後,你應該放棄條件拆分上的剩餘頭文件(我猜頭文件的結構與數據的結構相同) – vercelli

回答

2

這是一種方法。

  1. 創建2個平面文件連接管理器,並在設計模式下,瀏覽到每個樣本文件,所以你可以設置列等
  2. 對於沒有校驗行的平面文件連接管理器,將Header Rows to Skip保留爲0,對於具有校驗和行的平面文件連接管理器,將其設置爲,跳過前面的2行,如下所示。 enter image description here
  3. 將兩個連接管理器的DelayValidation屬性設置爲true
  4. 在數據流任務中,使用腳本組件檢測文件是否有校驗和行。
  5. 在腳本組件的輸出中,將文件的完整路徑作爲輸出列,並且還有一個標誌,指示文件是否具有校驗和行。例如:HasCheckSumRows
  6. 將腳本組件的輸出連接到條件分割任務。
  7. 在條件分割任務中,根據HasCheckSumRows劃分標記設置爲true,並創建2個輸出,其中1個用於帶有校驗和行的文件,其他用於無文件。
  8. 創建2個平面文件源,1個用於校驗和行文件,使用您爲這些類型的文件創建的平面文件連接管理器,另一個用於沒有校驗和行的常規文件。
  9. 將條件拆分的2個輸出連接到相應的平面文件源,使用輸出列中的完整文件路徑作爲平面文件源的connectionstring
  10. 最後,使用Union All組件將這兩種類型的文件中的行恢復爲1個輸入數據流。因此,這不會重複您的工作流程(即不會導致冗餘),因爲您擁有1個流中的所有行。

希望這是有道理的。

+1

它確實很有意義。我要測試它並返回結果。 –

0

我會在評論中寫這篇文章,但你知道我是使用多年後的新人。無論如何,只有具有冗餘數據流的Checksum行存在條件的選項1可能是最直接的方法,並且看到您的數據集列受限制可能是創建和維護最快的方法。對於這種方法,你可以放入一個Foreach循環容器來設置它來枚舉文件。添加一個變量來測試校驗和是否存在。添加一個c#腳本任務來測試校驗和並填充變量。然後添加2個數據流任務1來處理一種格式,另一種格式。它只會是4個組件(FileConnection,Dataflow,源,目標)的重複。然後對於優先約束編輯器(雙擊綠色箭頭)更改以通過Expression中的表達式和約束進行求值,根據正在饋送哪個數據流,只需選擇變量或!變量(相反)。這是假設你沒有首先將同一個數據流任務中的所有2000多個文件與工會等結合起來,那麼你將會陷入癱瘓。對於@Shiva回答肯定有很多交叉,但是我沒有看到需要對工會進行有條件的拆分所有如果你要去一個臨時表。

enter image description here

在不同的音符,如果你真的不想要的數據流任務等冗餘沒有必要運行SSIS包之前做的PowerShell腳本。你可以創建一個C#腳本在包中正確執行。例如,我遇到了一個問題,那就是我必須導入的數據源的行結尾不一致。所以我有一個c#腳本來標準化我的數據流任務之前保存文件的行尾。您可以將文件規範化爲ssis包中的一個結構,但是它會在您指出時需要額外的系統資源,但是它將在文件已被加載到內存/處理的時間。

@xpil,15是不同的類型是不是在原來的問題。那麼我可能會做2件事中的1件。首先實現你的想法#2,但在SSIS腳本中。所以我會通過system.file.io操作去除不需要的行。然後,我會構建出所有不同的類型,並在腳本中設置一個變量,以通過不同的dft來告訴您哪種類型是或是否失敗。或者我實際上只是腳本的整個操作,我可能會或可能不會使用SSIS,但我只是有一個system.file.io來加載文件檢測存在和類型,然後簡單地使用SQLBulkCopy把它放到表中,然後寧可比創建DFT更省時。儘管如果文件大小隻有幾百MB,你仍然可能想要去DFT路線。以下是我編寫的一個SSIS腳本任務的一些片段,當然您可能需要根據自己的目的進行修改。

如果要去修理文件和DFT路線。

string contents = File.ReadAllText(_WFRFullPath); 
    contents = Regex.Replace(contents, @"\r\n?|\n", crlf); 
    File.WriteAllText(_SSISWorkspaceFullPath, contents); 

通過正則表達式寫入文件將文件內容修復回新位置。

如果通過腳本路徑加載,則只需將其讀取到數據表中,然後可能按列名或數據類型測試格式。然後加載它。

 SqlConnection sqlConnection = new SqlConnection(sqlConnectionString); 
     sqlConnection.Open(); 

     SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnection); 
     bulkCopy.DestinationTableName = _stagingTableName; 
     foreach (DataColumn col in _jobRecDT.Columns) 
     { 
      //System.Windows.Forms.MessageBox.Show(col.ColumnName); 
      bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName); 
     } 


     bulkCopy.WriteToServer(_jobRecDT); 

     sqlConnection.Close(); 

注意,我沒有它了手的代碼,但如果你有大量的文件,你可以真正實現一個流讀取器和塊中的文件和bulkcopy起來。

+0

馬特,如果它只是一種文件類型,那麼你將是絕對正確的。事實上,在我的場景中,我有超過12,000個15(ish)不同類型的文件,每種類型都有兩種變體:有和沒有校驗和標題。所以我有一個合理的理由儘可能地去除冗餘。 –