2013-02-27 47 views
1

我正在使用平面文件目標將我的數據導出到文本文件。我需要將輸出文件大小限制爲1 MB。可能嗎?在SSIS中限制輸出平面文件大小

+1

你打算如何處理缺失的行? 你可以使用* SELECT TOP x ROWS WHERE ToExport = 1 * – jazzytomato 2013-02-27 13:03:55

回答

0

如果數據超過文件大小,則必須決定要忽略哪些數據。這只是你或你的顧客可以決定的。

然後編寫查詢以僅返回所需的數據。

0

一些想法:

使用腳本轉換,你必須擁有對你的邏輯「獲取下一行」的方法生成的類 - 這個類的添加計數器,並在每一行,你得到鍛鍊行的數據大小並將其添加到計數器。如果計數器的行數超過1mb,則不要將該行放入輸出緩衝區。

在控制流上使用腳本組件,調用.Net IO方法讀取文件的1mb並僅寫入該文件(這意味着您正在創建一個大文件然後縮小它)。

真的,SSIS不會做這兩個好。如果是我,我會選擇「SELECT TOP X」方法。

0

沒有任何東西可以在SSIS中實現;但是,對腳本轉換進行編碼相對比較簡單,該腳本轉換可以充當數據流目標,並且會限制其輸出文件的大小。根據需要添加一些代碼來創建多個文件(每個文件都小於指定的大小)並不難,因爲這需要存儲所有結果數據。

例如,假設您的源查詢是

SELECT 
    TABLE_CATALOG, 
    TABLE_SCHEMA, 
    TABLE_NAME, 
    COLUMN_NAME, 
    ORDINAL_POSITION, 
    COLUMN_DEFAULT, 
    IS_NULLABLE, 
    DATA_TYPE, 
    CHARACTER_MAXIMUM_LENGTH 
FROM INFORMATION_SCHEMA.COLUMNS 

,你就試着寫這一個或多個CSV文件,在不超過每個文件的一些特定的大小。

定義三個包級變量如下:

  • 用戶:: TargetFolder(包含文件夾名稱String要寫入)
  • 用戶:: TargetFileNamePattern(String用的命名模式輸出文件;例如SampleOutput{0}.csv
  • 用戶:: MaxFileLength(含有每個文件字符)
的最大數目

這樣創建您的數據流:

data flow screenshot

和惡意代碼的腳本轉換正是如此:

/* Microsoft SQL Server Integration Services Script Component 
* Write scripts using Microsoft Visual C# 2008. 
* ScriptMain is the entry point class of the script.*/ 

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

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute] 
public class ScriptMain : UserComponent 
{ 
    private int _fileCounter; 
    private int _bytesWritten; 
    private TextWriter _tw; 

    private TextWriter CurrentWriter 
    { 
     get 
     { 
      if (_tw == null) 
      { 
       string fileName = String.Format(this.Variables.TargetFileNamePattern, _fileCounter); 
       string filePath = Path.Combine(this.Variables.TargetFolder, fileName); 
       _tw = File.CreateText(filePath); 
      } 
      return _tw; 
     } 
    } 

    public override void PreExecute() 
    { 
     base.PreExecute(); 
     _fileCounter = 1; 
     _bytesWritten = 0; 
     _tw = null; 
    } 

    public override void PostExecute() 
    { 
     base.PostExecute(); 
     if (_tw != null) 
     { 
      _tw.Flush(); 
      _tw.Close(); 
     } 
    } 

    public override void Input0_ProcessInputRow(Input0Buffer Row) 
    { 
     string thisLine = String.Format(
       "{0},{1},{2},{3},{4},{5},{6},{7},{8}", 
       Row.TABLECATALOG, 
       Row.TABLESCHEMA, 
       Row.TABLENAME, 
       Row.COLUMNNAME, 
       Row.ORDINALPOSITION, 
       Row.COLUMNDEFAULT_IsNull ? "NULL" : Row.COLUMNDEFAULT, 
       Row.ISNULLABLE, 
       Row.DATATYPE, 
       Row.CHARACTERMAXIMUMLENGTH_IsNull ? "NULL" : Row.CHARACTERMAXIMUMLENGTH.ToString()); 
     if (_bytesWritten + thisLine.Length > this.Variables.MaxFileLength) 
     { 
      _tw.Flush(); 
      _tw.Close(); 
      _tw = null; 
      _fileCounter += 1; 
      _bytesWritten = 0; 
     } 
     this.CurrentWriter.WriteLine(thisLine); 
     _bytesWritten += thisLine.Length; 
    } 
} 

對於源查詢的每一行,這將構建要寫入的字符串,然後檢查將該字符串添加到當前的TextWriter是否會導致該文件太大。如果是這樣的話,當前文件被刷新到磁盤並關閉;下一次調用this.CurrentWriter將依次爲下一個文件創建一個新的TextWriter對象。