在脚本组件中使用后,包变量将丢失

时间:2014-04-18 17:30:00

标签: ssis

我有一个执行sql任务,它将结果集存储为具有object数据类型的包变量。我有一个执行数据流任务的foreach循环容器。在我的数据流任务中,我有一个充当数据源的脚本组件。我使用前面提到的包变量使用以下代码填充脚本组件的输出缓冲区:

public override void CreateNewOutputRows()
{
    DataTable dt = new DataTable();
    OleDbDataAdapter oleda = new OleDbDataAdapter();
    oleda.Fill(dt, this.Variables.ResultSet);

    foreach (DataRow row in dt.Rows)
    {
        Output0Buffer.AddRow();
        Output0Buffer.Column1 = Convert.ToInt64(row["Column1"].ToString());
        Output0Buffer.Column2 = Convert.ToInt64(row["Column2"].ToString());
    }
}

在循环的第一次迭代中,它工作正常。但是在随后的迭代中,包变量值将丢失。我的行没有记录。

2 个答案:

答案 0 :(得分:4)

此问题是由变量填充OleAdapter引起的,请参阅here

解决问题的方法是,不是填充RecordSet,而是使用ScriptComponent作为Destination,并直接填充DataTable。

1:创建Object类型的包变量(例如LookupTable)。

2:将其添加到设置为Destination的脚本组件的ReadWriteVariables中,执行此操作代替填充RecordSet

3:添加类似于下面的代码以填充新的DataTable:

public class ScriptMain : UserComponent
{
    //Create a new DataTable. This will end up getting passed around your package
    DataTable tbl = new DataTable();


public override void PreExecute()
    {
        base.PreExecute();

        //Set up the columns and PrimaryKey
        tbl.Columns.Add("Column1", typeof(int));
        tbl.Columns.Add("Column2", typeof(int));

        tbl.PrimaryKey = new DataColumn[] { tbl.Columns["Column1"] };

    }
        public override void PostExecute()
    {
        base.PostExecute();

        //Populate the PackageVariable with the newly create DataTable object.
        Variables.LookupTable = tbl;
    }

    public override void LookupInput_ProcessInputRow(LookupInputBuffer Row)
    {
        //Now populate the table with rows from your query
        tbl.Rows.Add(Row.Column1, Row.Column1);
    }

}

4:现在,您将来可以将变量直接转换为数据表:

var dataTable = (DataTable) Variables.LookupTable;

现在每次在脚本组件中运行查找时都不会被吹走,而且每次都不需要填充DataTable,这样可以节省宝贵的时间!

希望这有助于将来的任何人。

答案 1 :(得分:-1)

我将删除执行SQL任务,并将其SELECT语句移动到现有数据流任务中的OLE DB源组件中。这将取代脚本组件。我也会删除包变量,因为它会变得多余。