我有一个执行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());
}
}
在循环的第一次迭代中,它工作正常。但是在随后的迭代中,包变量值将丢失。我的行没有记录。
答案 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源组件中。这将取代脚本组件。我也会删除包变量,因为它会变得多余。