代码之家  ›  专栏  ›  技术社区  ›  salvationishere

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

  •  1
  • salvationishere  · 技术社区  · 14 年前

    我正在开发一个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 回复  |  直到 8 年前
        1
  •  1
  •   John Nicholas    14 年前

    如果项数组包含超过1个字符串,则会发生这种情况,因为您将设置多个参数=3*项数组中没有字符串。

    另外,您没有使用您在循环中拉出的字符串。

    这里似乎发生了一些演变。

    您需要坐下来计算是否要多次执行插入(现在您只执行一次)。

    还有其他方法可以设置参数类型,这样就不需要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来表示循环将发生多少次呢?

    ID还对字典执行计数,以确认其中有3个且只有3个项,因为无论您循环多少次,您都将插入相同的3个项。

    为什么不使用字典并使用参数名作为索引呢?或者以字符串的形式遍历键列表并以这种方式添加参数?

    像这样的

    /// <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的结构/类的原因是它可以有效地保护数据,使您的方法不受导致它爆炸的各种有害数据的影响。总是很好地让别人的代码行为,而不是应付他们所有的怪异排列。