5

これは SSIS 関連の問題です

オブジェクト型に設定された変数があります。1 つのデータフローがフィルター処理された行をレコードセットにインポートし、このレコードセットがオブジェクト変数に格納されます。

完全に別のデータフローでは、そのレコードセットをソースとして使用する必要があります。そこで、スクリプト コンポーネントを作成し、それがデータ ソースになることを伝えました。

必要な 3 つの出力列を持つように設定しました。私の問題は、レコードセットのすべての行を取得して、スクリプト コンポーネントに新しい行を作成するにはどうすればよいですか?

レコードセット変数を読み取り専用変数として渡しました。変数を foreach して各行に取得しようとすると、変数が取得列挙子メソッドを定義していないため、実行できません。

したがって、各行をそれらの列に出力できず、スクリプト コンポーネントをデータ ソースとして使用できません。

他の誰かが同様の状況に直面しましたか? 私は愚かなことをしていますか、それとも別の方法でそれをしましたか?

注として、スクリプトとVisual Studio 2008でC#を使用しています

4

3 に答える 3

7

そこで、少し調べて、問題のVBソリューションを見つけ、それをC#に変換すると、これがコンパイルされ、期待どおりに動作するようになりました。私が使用したコードはこれでした:

    DataTable datatable = new DataTable();
    System.Data.OleDb.OleDbDataAdapter oAdapter = new System.Data.OleDb.OleDbDataAdapter();

    oAdapter.Fill(datatable,ReadOnlyVariables["User::XXXXX"]);

    foreach (DataRow row in datatable.Rows)
    {
        Output0Buffer.AddRow();
        Output0Buffer.CoverAmount = Convert.ToInt32(row["XXXX"].ToString());
    } 

同様の問題に直面している他の人のために!

助けてくれてありがとう

于 2013-01-29T15:25:40.847 に答える
4

AndyLeonardのIncrementalLoadフレームワークの古いバージョンに基づいて同様のことを行います。子パッケージは、新しい、変更された、変更されていないなどの行数を示すレコードセットにデータを入力します。親パッケージでは、オブジェクトをテストして、使用する前にオブジェクトが設定されていることを確認します。私は会議にスキップする必要があるので、このコードはあなたの特定のニーズを完全には解決しないのでご容赦ください。私はあなたが何かをしたい場所のためにそこに擬似コードを持っています。

    public void Main()
    {
        bool debug = Convert.ToBoolean(Dts.Variables["Debug"].Value);
        string taskName = string.Empty;
        string packageName = string.Empty;
        string sourceName = string.Empty;
        bool fireAgain = false;

        taskName = Convert.ToString(Dts.Variables["TaskName"].Value);
        packageName = Convert.ToString(Dts.Variables["PackageName"].Value);
        // Fix this by defining and passing in params
        sourceName = Convert.ToString(Dts.Variables["TaskName"].Value);

        System.Data.OleDb.OleDbDataAdapter adapater = null;
        System.Data.DataTable table = null;
        System.Data.DataColumn column = null;
        System.Data.DataRow row = null;
        string message = string.Empty;

        object rowCounts = null;
        rowCounts = Dts.Variables["RowCounts"].Value;
        table = new DataTable();

        try
        {
            // Get us out of this crazy thing - should only be an issue
            // first pass through
            if (rowCounts == null)
            {
                Dts.TaskResult = (int)ScriptResults.Success;
                return;
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Failed here");
        }

        adapater = new System.Data.OleDb.OleDbDataAdapter();
        try
        {
            // This works if we pass in a dataset
            //adapater.Fill(table, Dts.Variables["RowCounts"].Value);
            adapater.Fill(table, rowCounts);
            // TODO: Enumerate through adapter
            // Call Output0Buffer.AddRow();
            // and Output0Buffer.MyColumn.Value = adapter[i].value // possibly casting to strong type
        }
        catch (Exception ex)
        {
            try
            {
                // This works if we use a datatable
                System.Data.DataSet ds = null;
                //ds = (DataSet)Dts.Variables["RowCounts"].Value;
                ds = (DataSet)rowCounts;
                table = ds.Tables[0];
                // TODO: Enumerate through datatable as we do with adapter

            }
            catch (Exception innerException)
            {
                // continue to swallow exceptions
            }
            Dts.Variables["ValidCounts"].Value = false;

            // trap "Object is not an ADODB.RecordSet or an ADODB.Record
            // parse ex.Message
            if (ex.Message.Contains("System.ArgumentException: "))
            {
                System.Text.StringBuilder exceptionMessage = null;
                exceptionMessage = new System.Text.StringBuilder();
                exceptionMessage.Append(ex.Message);
                exceptionMessage.Replace("\nParameter name: adodb", string.Empty);
                exceptionMessage.Replace("System.ArgumentException: ", string.Empty);

                if (exceptionMessage.ToString() != "Object is not an ADODB.RecordSet")
                {
                    Dts.Events.FireInformation(0, string.Format("{0}.{1}", packageName, taskName), exceptionMessage.ToString(), string.Empty, 0, ref fireAgain);
                }
            }
        }

        Dts.Variables["ValidCounts"].Value = false;
        if (table.Rows.Count > 0)
        {
            Dts.Variables["ValidCounts"].Value = true;
        }

        if (debug)
        {
            message = string.Format("SourceName:  {0}\nValidCounts:  {1}", sourceName, false);
            //System.Windows.Forms.MessageBox msgBox = null;
            //msgBox = new MessageBox();
            System.Windows.Forms.MessageBox.Show(message, string.Format("{0}.{1}", packageName, taskName));
            //MessageBox(message, string.Format("{0}.{1}", packageName, taskName));
        }

        Dts.TaskResult = (int)ScriptResults.Success;
    }
于 2013-01-29T15:09:04.103 に答える
0

OPと同じ問題に取り組んでいます。私の場合、それはオブジェクトであると想定し、それをデータテーブルに変換するのに多くの時間を費やしました。私が発見したのは、オブジェクトが既にデータテーブルであったため、SSIS スクリプト タスク コンポーネントから、次のように記述できたことです。

DataTable dt = (DataTable)ReadOnlyVariables["User::FTP_DataPath_File_Metadata"].Value;

foreach (DataRow row in dt.Rows)
{
    CustomOutputBuffer.AddRow();
    CustomOutputBuffer.FileName = row.ItemArray[0].ToString();
    CustomOutputBuffer.FileLastModified = Convert.ToDateTime(row.ItemArray[1]);
    CustomOutputBuffer.FileSize = Convert.ToInt32(row.ItemArray[2]);
}

これにより、スクリプト コンポーネントをソースとして使用して、「オブジェクト変数」がデータフローに正常に変換されました。

この例は、「メタデータを含むファイル リストの取得」の結果をオブジェクト変数に保存する Task Factory セキュア FTP コンポーネントに対応するために作成されました。

于 2016-11-04T20:05:22.213 に答える