In general, we define an array of SqlParameter parameters, such as:
sqlparameter[] Parms =
{
New SqlParameter ("@DateTime1", Dtbegin),
New SqlParameter ("@DateTime2", Dtend)
};
If only one SqlCommand is used, the argument for this condition is used, and no exception occurs, but if the parameter array is used for two SqlCommand, the following exception occurs:
System.ArgumentException: SqlParameter is already included in another sqlparametercollection.
The reasons are as follows: The declared SqlParameter array, and within the loop, every execution of ExecuteNonQuery (or other command methods) is performed by IDbCommand.Parameters.Add within the method ( IDbDataParameter) adds the SqlParameter array to the idataparametercollection of IDbCommand. The framework mechanism restricts two idataparametercollection from pointing to the same object. Although the ExecuteNonQuery method internally declares a IDbCommand temporary object, in theory, This IDbCommand object containing the idataparametercollection is freed from memory at the end of the ExecuteNonQuery method. But it may actually be that the garbage collection mechanism does not immediately reclaim the IDbCommand temporary objects, and the parameter set of object bindings also exists, just as a DropDownList adds item. This causes two idataparametercollection to point to the same object at the time of the next loop execution, and there is a problem.
Solution One: Regenerate the object at each iteration, but this produces a lot of garbage variables, which is undesirable.
Solution two: Empty the Parameters collection of command commands after the use is complete. It is recommended to use similar code as follows:
<summary>
Get a DataTable
</summary>
public static DataTable Getdatatable (
String conndbstr, String sql, params sqlparameter[] cmdparms)
{
SqlCommand cmd = new SqlCommand ();
using (SqlConnection conn = new SqlConnection (CONNDBSTR))
{
Preparesqlcommand (CMD, conn, NULL, SQL, cmdparms);
SqlDataAdapter da = new SqlDataAdapter (cmd);
DataTable dt = new DataTable (Setsqlasdatatablename (SQL));
Da. Fill (DT);
Cmd. Parameters.clear ();//More This sentence, solve the problem
return DT;
}
}
Also, if not an array, just a SqlParameter variable, such as:
SqlParameter parm =
New SqlParameter ("@Cust_Id", Custid.trim ());;
It is SqlCommand used many times, there is no problem, I have done the experiment!
The other sqlparametercollection already contains SqlParameter