另一個SqlParameterCollection中已包含SqlParameter


一般情況下,我們定義的一個SqlParameter參數數組,如:

            SqlParameter[] parms = 
            {
                new SqlParameter("@DateTime1", dtBegin),
                new SqlParameter("@DateTime2", dtEnd)
            };

如果只給一個SqlCommand使用,這種情況的參數使用,不會出現異常,但如果該參數數組同時給兩個Sqlcommand使用,就會出現如下異常:

  System.ArgumentException: 另一個SqlParameterCollection中已包含SqlParameter。

        原因如下:聲明的SqlParameter數組,而在循環的內部,每一次執行ExecuteNonQuery(或者其它命令方法)都由該方法內部的IDbCommand.Parameters.Add(IDbDataParameter)將SqlParameter數組添加到IDbCommand的IDataParameterCollection中。而framework機制限制兩個IDataParameterCollection指向同一個對象。雖然ExecuteNonQuery方法內部聲明了一個IDbCommand的臨時對象,理論上講,這個包含了IDataParameterCollection的IDbCommand對象會在ExecuteNonQuery方法結束時從內存中釋放。但是實際上可能是由於垃圾回收機制並沒有將IDbCommand臨時對象即時的回收,而且改對象綁定的Parameter集合也存在,就像一個DropDownList添加Item一樣。這樣在下一個循環執行的時候,會導致兩個IDataParameterCollection指向同一個對象,此時出現問題。
解決方案一:在每一次循環時,重新生成對象,但這樣會產生大量的垃圾變量,不可取。
解決方案二:將使用完之后的Command命令的Parameters集合清空。推薦使用,類似代碼如下:

        /// <summary>
        /// 獲取一個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();//多了這一句,就解決了問題
                return dt;
            }
        }

另外,如果不是數組,只是一個SqlParameter變量,如:

            SqlParameter parm = 
                new SqlParameter("@Cust_Id", CustId.Trim());;

則多次被SqlCommand使用,不會出現問題,我已經做了試驗!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM