代码改变世界

问题解决(另一个 OdbcParameterCollection 已包含带有 ParameterName“@****”的 OdbcParameter)

2006-06-25 15:09  BAsil  阅读(1051)  评论(0编辑  收藏

今天在用DAAB 3.1 连接Sybase ASE 9.1.2的时候又出现了

另一个 OdbcParameterCollection 已包含带有 ParameterName"@****"的 OdbcParameter

的问题,记得我半年前写过一个关于SqlParameterCollection的文章,翻出来看了一下,还真的找到了解决办法。这篇文章我已经发布到了现在的blog上,链接是

另一个 SqlParameterCollection 已包含带有ParameterName "@UserName"的SqlParameter

回到OdbcParameterCollection问题,我们来看看出错的代码


private GotDotNet.ApplicationBlocks.Data.Odbc odbc=new GotDotNet.ApplicationBlocks.Data.Odbc();
protected DataSet BXCredDS=new BaoXiaoPingZhengData();
///
///填充DataSet
///
string connstr=ConfigurationSettings.AppSettings["SQLconnstr"];
searchParms = new OdbcParameter[4];
searchParms[0]=new OdbcParameter("@bh",OdbcType.VarChar);
searchParms[1] = new OdbcParameter("@xh",OdbcType.Int);
searchParms[2]=new OdbcParameter("@code",OdbcType.VarChar);
searchParms[3]=new OdbcParameter("@je",OdbcType.Double);
foreach(DataRow dr in BXCredDS.Tables

[BaoXiaoPingZhengData.BAOXIAOMINGXI_TABLE].Rows)
{


searchParms[0].Value="0000000001";
searchParms[1].Value=Convert.ToInt32(dr[BaoXiaoPingZhengData.XUHAO_FIELD]);
searchParms[2].Value=dr[BaoXiaoPingZhengData.CODE_FIELD].ToString();
searchParms[3].Value=Convert.ToDecimal(dr[BaoXiaoPingZhengData.SUM_FIELD]);

odbc.ExecuteNonQuery(connstr,"insertYsqlBxMx",searchParms);

}


通过查阅另一个 SqlParameterCollection 已包含带有ParameterName "@UserName"的SqlParameter 一文,我觉得问题可能出在:

由于我在循环的外部声明了一个长度为4的OdbcParameter数组,而在循环的内部,每一次执行ExecuteNonQuery都由该方法内部的IDbCommand.Parameters.Add(IDbDataParameter)将OdbcParameter数组添加到IDbCommand的IDataParameterCollection中。而framework机制限制两个IDataParameterCollection指向同一个对象。虽然ExecuteNonQuery方法内部声明了一个IDbCommand的临时对象,理论上讲,这个包含了IDataParameterCollection的IDbCommand对象会在ExecuteNonQuery方法结束时从内存中释放。但是实际上可能是 由于垃圾回收机制并没有将IDbCommand临时对象即时的回收(猜测),这样在下一个循环执行的时候,会导致两个IDataParameterCollection指向同一个对象,此时出现问题。

经过修改问题解决,修改后的代码如下:


private GotDotNet.ApplicationBlocks.Data.Odbc odbc=new GotDotNet.ApplicationBlocks.Data.Odbc();
protected DataSet BXCredDS=new BaoXiaoPingZhengData();
///
///填充DataSet
///
string connstr=ConfigurationSettings.AppSettings["SQLconnstr"];

foreach(DataRow dr in BXCredDS.Tables[BaoXiaoPingZhengData.BAOXIAOMINGXI_TABLE].Rows)
{

searchParms = new OdbcParameter[4];
searchParms[0]=new OdbcParameter("@bh",OdbcType.VarChar);
searchParms[1] = new OdbcParameter("@xh",OdbcType.Int);
searchParms[2]=new OdbcParameter("@code",OdbcType.VarChar);
searchParms[3]=new OdbcParameter("@je",OdbcType.Double);

searchParms[0].Value="0000000001";
searchParms[1].Value=Convert.ToInt32(dr[BaoXiaoPingZhengData.XUHAO_FIELD]);
searchParms[2].Value=dr[BaoXiaoPingZhengData.CODE_FIELD].ToString();
searchParms[3].Value=Convert.ToDecimal(dr[BaoXiaoPingZhengData.SUM_FIELD]);

odbc.ExecuteNonQuery(connstr,"insertYsqlBxMx",searchParms);

}


P.S.由于本人对垃圾回收机制不是十分的了解,文章只是对解决实际应用问题的一种分析,欢迎大家探讨、指出不足。