【问题标题】:Enumerating RecordSet in DataFlow Script Component as Data Source枚举 DataFlow 脚本组件中的 RecordSet 作为数据源
【发布时间】:2013-01-29 14:48:35
【问题描述】:

这是一个与 SSIS 相关的问题

我有一个设置为对象类型的变量。一个 Dataflow 将一些过滤的行导入记录集中,并且该记录集存储在对象变量中。

在完全独立的数据流中,我需要使用该记录集作为源。所以我创建了一个脚本组件并告诉它它将是一个数据源。

我将其设置为具有我需要的三个输出列。我的问题是,如何让记录集中的每一行在脚本组件中创建一个新行?

我将记录集变量作为只读变量传递,当我尝试使用 foreach 变量获取每一行时,我无法做到这一点,因为该变量没有定义获取枚举器方法。

因此,我无法将每一行打印到这些列中,也无法将我的脚本组件用作数据源。

有没有其他人遇到过类似的情况?我是在做一些愚蠢的事情还是你用另一种方式做的?

作为说明,我在脚本和 Visual Studio 2008 中使用 C#

【问题讨论】:

  • 你用ADO ForEach枚举对象了吗?

标签: c# ssis


【解决方案1】:

所以我环顾四周,找到了一个 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());
    } 

对于遇到类似问题的任何其他人!

感谢大家的帮助

【讨论】:

    【解决方案2】:

    我根据 Andy Leonard's Incremental Load framework 的旧版本做了类似的事情。我们的子包填充一个记录集,指示我们有多少新的、更改的、未更改的等行数。在父包中,我们测试该对象以确保在使用它之前已填充它。我需要跳到一个会议,所以请原谅这段代码,因为它不能完全解决您的特定需求,但希望能在正确的方向上提供坚实的推动力,直到我可以回来为您的情况量身定制。我在那里有你想做的事情的伪代码。

        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;
        }
    

    【讨论】:

      【解决方案3】:

      我正在解决与 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]);
      }
      

      这成功地将我的“对象变量”转换为数据流,使用脚本组件作为源。

      这个例子是为了适应任务工厂安全 FTP 组件,它将“获取带有元数据的文件列表”的结果保存到对象变量中。

      【讨论】:

      • 这给了我Unable to cast COM object of type 'System.__ComObject' to class type 'System.Data.DataTable.'的错误
      猜你喜欢
      • 1970-01-01
      • 2013-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-14
      • 2018-01-27
      相关资源
      最近更新 更多