2

助けが必要です。

oledb ソースから .csv ファイルにデータをインポートしています。宛先にヘッダーが 2 回表示されないようにします。「最初のデータ行の列名」プロパティのチェックを外すと、最初の実行でもヘッダーが設定されません。

現時点でのアウトプット。

Col1,Col2
A,B
Col1,Col2
C,D

ファイルが空の場合にヘッダーが挿入されるようにパッケージを実行するにはどうすればよいですか。その後、実行が再び発生すると、ヘッダーは含まれず、データのみが含まれます。

同様のスレッドがありましたが、式を使用して目的地自体の行数を取得する方法として解決策を適用できませんでした。かなり前だったので新しく作りました。

よろしくお願いいたします。

-アクシャイ

4

4 に答える 4

7

おそらく私は何かが欠けているかもしれませんが、これは私にとってはうまくいきます。ColumnNamesInFirstDataRow で読み取り専用の問題が発生していません

という名前のパッケージ レベル変数を作成し、AddHeaderブール値を入力して、に設定しましたTrue。FFCM という名前のフラット ファイル接続マネージャーを追加し、HeadCount (int)、AddHeader (boolean) の 2 列の CSV 出力を使用するように構成しました。接続マネージャーのプロパティで、プロパティ「ColumnNamesInFirstDataRow」の式を追加し、値を割り当てました。@[User::AddHeader]

ここに画像の説明を入力

ファイルのサイズをテストするスクリプト タスクを追加しました。変数 AddHeader への読み取り/書き込みアクセスがあります。次に、このスクリプトを使用して、ファイルが空かどうかを判断しました。「空」の定義がヘッダー行があるということである場合、その長さに一致するように if チェックのロジックを調整します。

    public void Main()
    {

        string path = Dts.Connections["FFCM"].ConnectionString;

        System.IO.FileInfo stats = null;
        try
        {
            stats = new System.IO.FileInfo(path);
            // checking length isn't bulletproof based on how the disk is configured
            // but should be good enough
            // http://stackoverflow.com/questions/3750590/get-size-of-file-on-disk
            if (stats != null && stats.Length != 0)
            {
                this.Dts.Variables["AddHeader"].Value = false;
            }
        }
        catch
        {
            // no harm, no foul
        }
        Dts.TaskResult = (int)ScriptResults.Success;
    }

追加シナリオを確実に生成するために、2 回ループしました。

ここに画像の説明を入力

ファイルを削除してパッケージを実行しましたが、ヘッダーは 1 回しかありませんでした。

ここに画像の説明を入力

于 2013-05-07T04:41:38.817 に答える
2

次の解決策は私にとってはうまくいきました。次のことも試すことができます。

  1. 3 つの変数を作成します。

IsHeaderRequired RowCount TargetFilePath

  1. SQL 実行タスクを使用してソース行数を取得し、変数に保存し RowCountます。
  2. スクリプト タスクがあります。TargetFilePath読み取り専用変数と を追加しますRowCount。読み取りおよび書き込み変数を追加しますIsHeaderRequired
  3. スクリプトを編集して、次のコード行を追加します。

        string targetFilePath = Dts.Variables["TargetFilePath"].Value.ToString();
        int rowCount = (int)Dts.Variables["RowCount"].Value;
    
        System.IO.FileInfo targetFileInfo = new System.IO.FileInfo(targetFilePath);
    
        if (rowCount > 0)
        {
            if (targetFileInfo.Length == 0)
            {
                Dts.Variables["IsHeaderRequired"].Value = true;
            }
            else
            {
                Dts.Variables["IsHeaderRequired"].Value = false;
            }
        }
    
        Dts.TaskResult = (int)ScriptResults.Success;
    
  4. スクリプト コンポーネントをデータベースに接続する

  5. フラット ファイル (ターゲット ファイル) の接続マネージャーをクリックし、プロパティに移動します。式では、スクリーンショットに示すように次のように記述します。

    Map the connectionString to variable "TargetFilePath".
    Map the ColumnNamesInFirstDataRow to "IsHeaderRequired".
    

フラット ファイル接続マネージャーの式。 ここに画像の説明を入力

最終パッケージ[スクリーンショット]:

ここに画像の説明を入力

お役に立てれば

于 2013-05-07T09:31:21.550 に答える
1

解決策 ....

まず、SSIS 整数変数を Foreach ループ以上のスコープに追加し (これを RowCount と呼びます)、既定値を負にします (これは重要です!)。次に、データ フローに行数を追加し、その結果を先ほど作成した RowCount SSIS 変数に割り当てます。3 番目に、接続マネージャーを選択し (ダブルクリックしないでください)、[プロパティ] ウィンドウ (F4) を開きます。Expressions プロパティを見つけて選択し、省略記号 (...) ボタンをクリックします。ColumnNamesInFirstDataRow プロパティを選択し、次のような式を使用します。

[@User::RowCount] < 0

これで、パッケージが開始されると、RowCount の静的な値は -1 または別の負の数になります。ループで初めてデータ フローが開始されると、ColumnNamesInFirstDataRow プロパティの値は TRUE になります。最初のデータ フローが完了すると、行数 (ゼロであっても) が RowCount 変数に書き込まれます。ループの 2 回目の反復で、接続マネージャーは列名を書き込まないように再構成されます...


于 2013-05-08T13:44:38.307 に答える