0

以下のコードを使用して C# で ssis パッケージを作成していますが、このコードを作成するとエラーが発生します。

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

    [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
    public class ScriptMain : UserComponent
    {

        public override void PreExecute()
        {
            base.PreExecute();
        }
        public override void PostExecute()
        {
            base.PostExecute();
        }
        string toreplace = "[~!@#$%^&*()_+`{};':,./<>?]";
        string replacewith = "";
        public override void Input0_ProcessInputRow(Input0Buffer Row)
        {
            Regex reg = new Regex(toreplace);
            Row.NaN = reg.Replace(Row.Na, replacewith);


        }

    }

エラーは

The best overloaded method match for 
'System.Text.RegularExpressions.Regex.Replace(string,System.Text.RegularExpressions.MatchEvaluator)' has some invalid arguments

これNaは入力列でNaNあり、出力列はどちらも入力列に特殊文字を含む varchar です。

例外:

System.ArgumentNullException
System.ArgumentOutofRangeException

これは、SSIS パッケージの BufferWrapper のコードです。

/* THIS IS AUTO-GENERATED CODE THAT WILL BE OVERWRITTEN! DO NOT EDIT!
*  Microsoft SQL Server Integration Services buffer wrappers
*  This module defines classes for accessing data flow buffers
*  THIS IS AUTO-GENERATED CODE THAT WILL BE OVERWRITTEN! DO NOT EDIT! */



    using System;
    using System.Data;
    using Microsoft.SqlServer.Dts.Pipeline;
    using Microsoft.SqlServer.Dts.Pipeline.Wrapper;

    public class Input0Buffer: ScriptBuffer

    {
        public Input0Buffer(PipelineBuffer Buffer, int[] BufferColumnIndexes, OutputNameMap OutputMap)
            : base(Buffer, BufferColumnIndexes, OutputMap)
        {
        }

        public BlobColumn Na
        {
            get
            {
                return (BlobColumn)Buffer[BufferColumnIndexes[0]];
            }
        }
        public bool Na_IsNull
        {
            get
            {
                return IsNull(0);
            }
        }

        public Int32 NaN
        {
            set
            {
                this[1] = value;
            }
        }
        public bool NaN_IsNull
        {
            set
            {
                if (value)
                {
                    SetNull(1);
                }
                else
                {
                    throw new InvalidOperationException("IsNull property cannot be set to False. Assign a value to the column instead.");
                }
            }
        }

        new public bool NextRow()
        {
            return base.NextRow();
        }

        new public bool EndOfRowset()
        {
            return base.EndOfRowset();
        }

    }

データフロー

ここに画像の説明を入力

スクリプト コンポーネント、入力列

ここに画像の説明を入力

スクリプト コンポーネント、実際のスクリプト

ここに画像の説明を入力

4

1 に答える 1

4

あなたのコードはほとんど問題ありません。Na列が NULLである可能性をテストしていません。おそらく、ソース データで null が許可されていないため、テストする必要はありません。

メンバー レベルで Regex をスコープし、PreExecute メソッドでインスタンス化することでパフォーマンスを向上させることができますが、それは単なるパフォーマンスの問題です。表示されるエラー メッセージとは関係ありません。

私のパッケージと期待される結果を見ることができます。4 つの行を送信しました。1 つは NULL 値、1 つは変更してはならない行、2 つは変更が必要な行です。

私のデータの流れ

カメレオンの質問で使用している手順に合わせて、データ フローを更新しました。

データフロー

マイ ソース クエリ

2 列のデータと 4 行分のデータを生成します。元の質問に一致する Na 列は varchar 型です。列 Agency_Names は、その後の更新に一致するように、非推奨の Text データ型としてキャストされます。

SELECT 
    D.Na
,   CAST(D.Na AS text) AS Agency_Names
FROM
(
SELECT 'Hello world' AS Na
UNION ALL SELECT 'man~ana'
UNION ALL SELECT 'p@$$word!'
UNION ALL SELECT NULL
) D (Na);

データ変換

OLE DB ソースの後にデータ変換変換を追加しました。あなたが行ったことを反映して、私はを長さ 50Agency_Nameのデータ型に変換しstring [DT_STR]、「Copy of Agency_Name」として別名を付けました。

データ変換

メタデータ

この時点で、データ フローのメタデータのタイプが DT_STR または DT_WSTR であることを確認します。これは、今後の正規表現の呼び出しで許可される唯一の入力です。Copy of Agency_Namesそれが期待されるデータ型であることを確認しました。

ここに画像の説明を入力

スクリプト タスク

列に読み取り専用の使用法を割り当てNaCopy of Agency_Name後で「AgencyNames」としてエイリアスを付けました。

ここに画像の説明を入力

元の質問に一致する NaN という 2 つの出力列を追加し、AgencyNamesCleaned を作成しました。これらは両方とも DT_STR、コードページ 1252、長さ 50 に設定されています。

ここに画像の説明を入力

これは私が使用したスクリプトです。

public class ScriptMain : UserComponent
{

    string toreplace = "[~!@#$%^&*()_+`{};':,./<>?]";
    string replacewith = "";


    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        Regex reg = new Regex(toreplace);

        // Test for nulls otherwise Replace will blow up
        if (!Row.Na_IsNull)
        {
            Row.NaN = reg.Replace(Row.Na, replacewith);
        }
        else
        {
            Row.NaN_IsNull = true;
        }

        if (!Row.AgencyNames_IsNull)
        {
            Row.AgencyNamesCleaned = reg.Replace(Row.AgencyNames, replacewith);
        }
        else
        {
            Row.AgencyNamesCleaned_IsNull = true;
        }
    }

}

根本原因分析

あなたの中心的な問題は、Naあなたが持っている列が文字列と互換性のある型ではないということだと思います。Sriramのコメントは的を射ています。列の自動生成されたコードを見るとNa、私の例では

    public String Na
    {
        get
        {
            return Buffer.GetString(BufferColumnIndexes[0]);
        }
    }
    public bool Na_IsNull
    {
        get
        {
            return IsNull(0);
        }
    }

ソース システムは、SSIS がこの列をバイナリ データと見なすようなメタデータを提供しています。おそらく、ホストの NTEXT/TEXT または n/varchar(max) です。正規表現の互換オペランドにするために何かをする必要があります。ソースの列の型をクリーンアップしますが、それができない場合は、Data Conversion変換を使用して DT_STR/DT_WSTR 型にします。

デノウマン

最初の画像に添付されているデータ ビューアーで、NaN と AgencyNamesCleaned が問題のある文字を正しく削除したことを確認できます。さらに、私のスクリプト タスクには、あなたのように赤い X が付いていないことがわかります。これは、スクリプトが無効な状態であることを示しています。

データ変換コンポーネントから "Copy of Agency_Names" 列を DT_TEXT として作成し、それをスクリプト コンポーネントに接続してから、データ変換コンポーネントでデータ型を変更したため、スクリプトの赤い X は、変換はそのメタデータを更新します。スクリプトを開き、適切な測定のために再コンパイル (ctrl-shift-b) をクリックします。

reg.Replace(...コードに下線を入れないでください。存在する場合は、伝えられていない問題の別の側面があります。その時点での私の最善のアドバイスは、私が説明したとおりに概念実証パッケージを再作成することです。それが機能する場合、機能しているものと機能していないものの違いを見つける練習になります。

于 2013-08-14T03:03:58.567 に答える