【问题标题】:Convert DTS.Variables of type System.Object into a list将 System.Object 类型的 DTS.Variables 转换为列表
【发布时间】:2019-05-28 16:21:59
【问题描述】:

我有一个 SSIS 包,它执行 SQL 任务以获取我需要连接的服务器的名称。然后,该查询的结果存储在一个名为“服务器”的变量对象中。然后我想一次在每台服务器上运行另一个包,所以我想拆分“servers”变量。但是,当我在 C# 脚本任务中执行此操作时,我不断收到错误消息:

错误:脚本任务的 0x1:调用的目标已引发异常。

这是拆分服务器变量的代码:

错误:脚本任务的 0x1:调用的目标已引发异常。

public void Main()
{
    var serverlist = (string[])Dts.Variables["User::servers"].Value;

    Dts.Variables["server1"].Value = serverlist[0];
    Dts.TaskResult = (int)ScriptResults.Success;
}

这应该是一个非常简单的代码,但由于某种原因,它不起作用。

【问题讨论】:

    标签: c# sql-server ssis etl script-task


    【解决方案1】:

    从您的问题标题看来,您似乎正在尝试从 SSIS 对象变量填充 C# 列表。如果这是正确的,则可以按如下方式进行。您可以使用 SSIS 对象变量的内容填充 DataTable 对象,或者如果您正在寻找专门使用列表,则可以从 DataTable 填充列表,然后您可以在此之后使用该列表。在下面的示例中,OleDBDataAdapter 用于使用 Fill 方法从 SSIS 对象变量填充 DataTable 对象。从对象变量中填充的数据可以通过DataTable中的DataRow对象访问。由于看起来 SSIS 对象变量只包含一个列,因此可以从下面每个 DataRowdr[0] 的列索引 0 访问它。您可能已经这样做了,但请确保 SSIS 对象变量位于脚本任务的 ReadOnlyVariables 字段中。

    using System.Collections.Generic;
    using System.Data;
    using System.Data.OleDb;
    
    
    List<string> serverNamesList = new List<string>();
    
    OleDbDataAdapter dtAdapter = new OleDbDataAdapter();
    DataTable serverNamesDataTable = new DataTable();
    
    //populate data table
    dtAdapter.Fill(serverNamesDataTable, Dts.Variables["User::ObjectVariable"].Value);
    
    foreach (DataRow dr in serverNamesDataTable.Rows)
    {
        //either access server names from column index 0 of DataRow or add to list
        serverNamesList.Add(dr[0].ToString()); 
    }
    

    【讨论】:

      【解决方案2】:

      既然你提到了:

      我有一个 SSIS 包,它执行 SQL 任务以获取服务器的名称

      主要问题在以下行:

      var serverlist = (string[])Dts.Variables["User::servers"].Value;
      

      执行 SQL 任务不返回字符串列表,它返回一个记录集对象。为了在脚本任务中阅读它,您必须遵循以下帖子(您必须使用 OledbAdapter)

      【讨论】:

        【解决方案3】:
        1. 创建一个新的包变量并命名为ConnectionStringOle
        2. 添加 ForEach 循环
        3. 类型: Foreach ADO 枚举器
        4. ADO 对象源变量: 选择 ObjectR。
        5. 枚举器模式:所有表中的行(仅限 ADO.NET 数据集)
        6. 在变量映射中,将结果映射到步骤 1 中的新包变量
        7. 修改 SQL 服务器连接管理器,将 ConnectionString 属性设置为 ConnectionStringOle 值。

        从那里开始,为每个循环迭代做任何你需要做的事情。

        注意:如果您只是提取服务器实例的名称,那么您应该创建另一个包变量,将实例的名称解析为整个 ConnectionString 值。您可以通过将现有 ConnectionString 的值复制到变量表达式中来获得此信息。

        【讨论】:

        • 因此,为了减少执行时间,我尝试同时执行多个包。由于将执行的包是 SQL 查询,因此它们可以在每台服务器上启动唯一的查询。循环是等待包完成还是继续?我最初正在执行您建议的方法,但是需要同时在每个服务器上执行 SQL 语句。
        • @GoodVibrations 由于服务器实例名称控制循环,因此您将按顺序在每台服务器上单独执行一个事务 - 它们不会并发。如果您需要同时在每台服务器上执行查询,那么循环将不起作用,因为这是设置单个连接管理器的原因。问题,如果您需要同时执行包,是否存在竞争条件?
        • 我以前从未做过比赛条件。那是什么?如果它有助于同时执行包,我会尝试。
        • @GoodVibrations 比赛条件不是好事,而是坏事。 searchstorage.techtarget.com/definition/race-condition
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-28
        • 2011-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多