过程或函数AppendDataCT指定了太多参数

时间:2010-06-07 13:23:59

标签: c# dictionary sql-server-2005 visual-studio-2008

我正在开发一个C#VS 2008 / SQL Server网站应用程序。我是ASP.NET的新手。我收到上面的编译器错误。你能就如何解决这个问题给我建议吗?

代码段:

    public static string AppendDataCT(DataTable dt, Dictionary<int, string> dic)
    {
        string connString = ConfigurationManager.ConnectionStrings["AW3_string"].ConnectionString;
        string errorMsg;

        try
        {
SqlConnection conn2 = new SqlConnection(connString);
SqlCommand cmd = conn2.CreateCommand();
cmd.CommandText = "dbo.AppendDataCT";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = conn2;
SqlParameter p1, p2, p3;
foreach (string s in dt.Rows[1].ItemArray)
{
    DataRow dr = dt.Rows[1]; // second row
    p1 = cmd.Parameters.AddWithValue((string)dic[0], (string)dr[0]);
    p1.SqlDbType = SqlDbType.VarChar;
    p2 = cmd.Parameters.AddWithValue((string)dic[1], (string)dr[1]);
    p2.SqlDbType = SqlDbType.VarChar;
    p3 = cmd.Parameters.AddWithValue((string)dic[2], (string)dr[2]);
    p3.SqlDbType = SqlDbType.VarChar;
}

conn2.Open();
cmd.ExecuteNonQuery();

这最后一行出错了。

这是SP:

ALTER PROCEDURE [dbo].[AppendDataCT] 
@col1 VARCHAR(50), 
@col2 VARCHAR(50),
@col3 VARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @TEMP DATETIME
SET @TEMP = (SELECT CONVERT (DATETIME, @col3))

INSERT INTO Person.ContactType (Name, ModifiedDate)
VALUES( @col2, @TEMP)
END

1 个答案:

答案 0 :(得分:1)

如果您的item数组包含多于1个字符串,则会发生这种情况,因为您将在item数组中设置多个参数= 3 * No Strings。

你也没有使用你在循环中拔出的字符串。

这里似乎有一些进化。

您需要坐下来确定是否要多次执行插入(现在只执行一次)或不执行。

还有其他方法可以设置参数的类型,因此您不需要p1,2,3变量btw。

我怀疑你想做更像这样的事情

    public static string AppendDataCT(DataRow dr, Dictionary<int, string> dic) 
        { 


            string connString = ConfigurationManager.ConnectionStrings["AW3_string"].ConnectionString; 
            string errorMsg; 

            try
            {
                SqlConnection conn2 = new SqlConnection(connString);
                SqlCommand cmd = conn2.CreateCommand();
                cmd.CommandText = "dbo.AppendDataCT";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection = conn2;
                SqlParameter p1, p2, p3;

                    p1 = cmd.Parameters.AddWithValue((string) dic[0], (string) dr[0]);
                    p1.SqlDbType = SqlDbType.VarChar;
                    p2 = cmd.Parameters.AddWithValue((string) dic[1], (string) dr[1]);
                    p2.SqlDbType = SqlDbType.VarChar;
                    p3 = cmd.Parameters.AddWithValue((string) dic[2], (string) dr[2]);
                    p3.SqlDbType = SqlDbType.VarChar;
                    conn2.Open();
                    cmd.ExecuteNonQuery();
                    conn2.Close();

            }

虽然这行

    foreach (string s in dt.Rows[1].ItemArray)

真让我感到困惑......我认为你在这里做错了什么 - 它告诉我你要做什么并且看起来很困惑。在6个月的时间里,你将不知道这是如何工作的。此外,呼叫者可能会在许多方面行为不端,只会在运行时捕获。

为什么不直接传入一个int来说明循环会发生多少次?

我也会在字典上执行一次计数,以确认其中只有3个项目,因为无论你循环多少次,你都会插入相同的3个项目。

为什么不使用字典并使用param名称作为索引?或者将键列表作为字符串循环并以这种方式添加参数?

像这样的事情

/// <summary>
        /// 
        /// </summary>
        /// <param name="dic">key = param name, val = param value</param>
        /// <returns></returns>
        public static string AppendDataCT(Dictionary<string, string> dic) 
    { 

        if (dic.Count !=3 )
            throw new ArgumentOutOfRangeException("dic can only have 3 parameters");

        string connString = ConfigurationManager.ConnectionStrings["AW3_string"].ConnectionString; 
         // you probably want to do a string.IsNullOrEmpty(connString) and throw a ConfigurationException here is true to quickly identify this annoying bug ...


           using(SqlConnection conn2 = new SqlConnection(connString))
           {
            using( SqlCommand cmd = conn2.CreateCommand())
            {
            cmd.CommandText = "dbo.AppendDataCT";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Connection = conn2;

            foreach (string s in dic.Keys)
            {                    
                SqlParameter  p = cmd.Parameters.AddWithValue(s, dic[s]);
                p.SqlDbType = SqlDbType.VarChar;
            }

            conn2.Open();
            cmd.ExecuteNonQuery();
            conn2.Close();
           }
           }
        }

该代码远非完美,但可能与您的意思相似。

如果您确实想要进行多次插入,那么可以考虑使用list<dictionary<string,string>> 或者更好地创建一个简单的结构来保存参数并拥有结构列表并将其传入.args的结构/类的原因是它可以对数据进行验证以保护您的方法免受各种恶意数据的影响导致它爆炸。总是很高兴让别人的代码行为而不是应对他们所有的bizzarre排列。