我有一个包,里面有两个组件:第一个是执行和获取ADO结果集的SQL任务,第二个是脚本任务,我将结果集转换为System.Data.DataTable
两次,类似的东西:
System.Data.DataTable t1= new System.Data.DataTable();
OleDbDataAdapter adp = new OleDbDataAdapter();
adp.Fill(t1, Dts.Variables["ResultSet"].Value);
System.Data.DataTable t2= new System.Data.DataTable();
OleDbDataAdapter adp2 = new OleDbDataAdapter();
adp2.Fill(t2, Dts.Variables["ResultSet"].Value);
结果是t1正确填充,但t2仍为空;更重要的是,我已经明确地将[User::ResultSet]
设置为只读变量,似乎变量刚刚被清空,即使我稍后再添加一个脚本任务并再次执行相同的操作,填充的DataTable
仍然是空。
有很多方法可以绕过我的案子,所以我不希望在这里找到解决方案。但我想弄清楚这些事情:OleDbDataAdapter.Fill
是否对原始数据集有副作用,我的只读变量如何更改其值?
答案 0 :(得分:4)
我不认为这会改变Read-Only Recordset变量值,问题是当使用Adapter.Fill方法用记录集填充数据表时,Record集仍然打开你必须关闭它明确地能够与其他适配器一起使用它。 (当你再次尝试从中读取时,它已完成提供行,所以你试图从最后读取)
来自以下Microsoft文章:
小心将ADO Recordset或Record对象与.NET Framework应用程序结合使用时,请在完成后始终调用Close。这样可以确保及时释放与数据源的基础连接,还可以防止在现有引用仍然存在时由于垃圾回收而回收非托管ADO对象而导致的可能的访问冲突。
请注意,当Fill操作完成时,采用DataSet和ADO对象的OleDbDataAdapter.Fill重载会隐式调用ADO对象上的Close。在调用带有DataTable的OleDbDataAdapter.Fill重载之后,您需要显式关闭ADO Recordset或Record对象。
我在使用Fill方法后并没有真正找到如何关闭SSIS记录集,但是我找到了类似问题的链接,并找到了解决方法:
答案 1 :(得分:0)
Fill使用指针来了解它正在读取的源数据集中的位置。第一次填充后,您就在变量数据集的末尾。首先将DTS变量分配给脚本变量:
var d = Dts.Variables["ResultSet"].Value.ToList();
应该让你多次使用它。见DataReader cursor rewind