Flat File Destination を使用して、データをテキスト ファイルにエクスポートしています。出力ファイルのサイズを 1 MB に制限する必要があります。出来ますか?
3 に答える
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
ファイルごとに特定のサイズを超えずに、これを 1 つ以上の CSV ファイルに書き込もうとしています。
次のように、3 つのパッケージ レベルの変数を定義します。
- User::TargetFolder (
String
書き込み先のフォルダー名を含む) - User::TargetFileNamePattern (
String
出力ファイルの命名パターンを使用; 例SampleOutput{0}.csv
) - User::MaxFileLength (
Int32
ファイルごとの最大文字数を含む)
次のようにデータ フローを作成します。
スクリプト変換を次のようにコーディングします。
/* 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
オブジェクトを作成します。
データがファイルサイズを超える場合は、どのデータを省略するかを決定する必要があります。それはあなたかあなたの顧客だけが決めることができるものです。
次に、必要なデータのみを返すクエリを記述します。
いくつかのアイデア:
スクリプト変換を使用すると、ロジックの「次の行を取得」メソッドを持つクラスが生成されます。そのクラスにカウンターを追加し、各行で行のデータのサイズを計算して追加します。カウンターへ。カウンターが 1 MB 相当の行を超える場合、その行を出力バッファーに入れません。
制御フローでスクリプト コンポーネントを使用し、.Net IO メソッドを呼び出して 1 MB のファイルを読み取り、そのファイルのみを書き戻します (これは、大きなファイルを作成してから縮小していることを意味します)。
実際、SSIS はこれらのいずれもうまく機能しません。私だったら、「SELECT TOP X」アプローチを採用します..