Ssis

分割平面文件的 SSIS 或 SQL Server 方式

  • October 10, 2015

我有幾十萬個包含單列值的平面文本文件。前 40 個值是參數,後跟 4000 - 8000 行感測器數據。這些文件只導入一次,永遠不會改變,並且可以通過參數選擇進行訪問,以進行進一步的分析/計算。

我認為使用兩張表(一張用於參數,一張用於感測器數據)將是一個很好的模式。所以我需要在導入後拆分文件,將參數行轉置為列,然後將所有感測器數據載入到一個表中,並用一個鍵返回參數表中的行。

我查看了 pivot 和 unpivot ,但這不會讓我將單行轉換為列。

關於如何在 SSIS 或 SQL 中執行此操作的任何幫助以及對我的架構的想法表示讚賞我不確定當我在感測器數據表中獲得幾百萬行時數據庫是否會響應。

使用 ssis 和一些 c#/vba

  • 添加一個 foreach 循環來遍歷文件

  • 創建一個用於鍵的變數(每次迭代遞增)

  • 在循環中添加一個數據流,包括

    • 從文件中讀取前 40 行並進行透視的腳本轉換(源)
    • 用於添加鍵的派生列(來自 var)
    • 餐桌的目的地
  • 在循環中添加一個數據流,包括

    • 跳過前 40 行並閱讀其餘部分的腳本轉換(原始碼)
    • 用於添加鍵的派生列(來自 var)
    • 餐桌的目的地
  • $$ optional $$使用文件任務刪除或移動文件

旋轉程式碼會將前 40 行讀入一個數組,然後將輸出列映射到數組的索引。

可能需要考慮確保密鑰在後續執行中保持唯一,並且可能需要從現有數據初始化為 max(key) + 1,為此使用 sql 任務。

為了能夠將PIVOT值轉換為目標表的形狀,您Parameter需要一組 (parameter_name, parameter_value) 元組。我假設設計能夠將一個參數值與另一個參數值區分開來,要麼是因為它在文件中的位置(第 1 行是參數 A 等),要麼是因為行中的標籤(ParamA=ValueA 等)。

對於位置設計,創建一個包含兩列的參考表 -row_numberparameter_name相應地填充它。使用標識列和parameter_value. 將參數行從單個源文件導入此臨時表。值將由標識按照行在源文件中出現的順序生成,因此第一個參數值將是 ID=1,最後一個參數值將是 ID=40。加入暫存表和引用表以獲取元組。

對於嵌入式標籤,使用字元串函式來分隔分隔符上的名稱和值。使用兩個暫存表會更簡單 - 一個使用單列保存文件中的原始記錄,第二個使用兩列parameter_name單獨保存parameter_value

我建議您分兩步導入每個文件。在步驟 1 中引入代表參數的 40 行。在步驟 2 中引入剩餘的數據行。 BULK INSERTFIRSTROWLASTROW可以控制它的參數。bcp 實用程序具有類似的開關。

現在您有一組 40 個 (parameter_name, parameter_value) 元組,可以將它們PIVOT編輯到表的模式中。使用這個表INSERTParameter它可能會有一個代理主鍵,你可以擷取它(這INSERT .. OUPUT會有所幫助)。BULK INSERT在其餘數據點中使用此值。這就是為什麼我建議分兩步進行。

把整個東西打包成一個儲存過程。使用 Powershell 腳本迭代您的文件並為每個文件呼叫 SP。您將需要對BULK INSERT. 如果您使用臨時表作為臨時表,您可以並行執行任意數量的處理流,而無需擔心整理。

在處理每個文件之前TRUNCATE,暫存表。這將重置身份並刪除先前文件的值。

當然,可以將整個文件讀入臨時表,然後將參數從感測器數據中分離出來。這同樣有效,在我看來,它只是代表了額外的執行時工作,價值不大。

引用自:https://dba.stackexchange.com/questions/102321