解决 过程或函数sp_updateItems指定了太多参数。

匿名

活跃的成员
已加入
2020年9月29日
留言内容
38
编程经验
Beginner
我想更新数据库中物品的价格。我正在从另一个列表(具有其他信息的类类型)中提取项目列表。之后,我将其(项目编号)作为存储过程参数一一发送,以获取价格更新。
但是我得到一个过程或函数sp_updateItems有太多的参数指定异常,即使我一次只发送一项作为参数,而我的存储过程也只接受一个参数。

C#:
 private void UpdatePrice(List<ListItem> accounts)
        {

            var items = (from item in accounts
                                 select item.itemNumbers);

            con = new SqlConnection(connection);
            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "sp_updateItems";
            con.Open();
            foreach (var item in items)
            {

                cmd.Parameters.AddWithValue("@itemnumber", item.ToString());
                cmd.Connection = con;
                int n = cmd.ExecuteNonQuery();
                if (n > 0)
                    Console.WriteLine("Price Updated Successfully");
                else
                    Console.WriteLine("Failed");
               
            }
            con.Close();
            //foreach(var item in items)
            //{
            //    Console.WriteLine(string.Join(", ", item));
            //}
            Console.ReadKey();
        }

我的存储过程是

C#:
create proc sp_updateItems
(
@itemnumber varchar(20)
)
as
begin
update 站 set Newprice = price*2
where [email protected]
end
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,501
地点
弗吉尼亚州切萨皮克
编程经验
10+
Notice on line 15 that you are calling AddWithValue() to the same cmd.

您只需要添加一次该参数,并且每次添加一次后都只需不断更改该值即可。
 

匿名

活跃的成员
已加入
2020年9月29日
留言内容
38
编程经验
Beginner
Notice on line 15 that you are calling AddWithValue() to the same cmd.

您只需要添加一次该参数,并且每次添加一次后都只需不断更改该值即可。
我真的不明白,这不是每次迭代一次将一个项目发送到存储过程的代码。到底出了什么问题?
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,504
地点
悉尼,澳大利亚
编程经验
10+
您是说要在每次迭代中创建一个新的Sqlcommand对象?
No, he means what he said. You have one command object and that is all you need. You then need to add one parameter to that command. Inside the loop, you need to set the Value of that one and only parameter. As it stands, you're adding a parameter on each iteration so you end up with two parameters on the second iteration, which is too many. If the code kept going, you'd end up with three parameters on the third iteration and N parameters on the Nth iteration. You need to have only one parameter the whole time, so just add one at the start.
 

匿名

活跃的成员
已加入
2020年9月29日
留言内容
38
编程经验
Beginner
No, he means what he said. You have one command object and that is all you need. You then need to add one parameter to that command. Inside the loop, you need to set the Value of that one and only parameter. As it stands, you're adding a parameter on each iteration so you end up with two parameters on the second iteration, which is too many. If the code kept going, you'd end up with three parameters on the third iteration and N parameters on the Nth iteration. You need to have only one parameter the whole time, so just add one at the start.
好的,所以我这样做了,但是获取SqlParameter已经被另一个SqlParameterCollection包含了。例外。

C#:
 private void UpdatePrice(List<ListItem> accounts)
        {

            var items = (from item in accounts
                                 select item.itemNumbers);

            con = new SqlConnection(connection);
            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "sp_updateItems";
            SqlParameter param = new SqlParameter();
            param.ParameterName = "@itemnumber";
            con.Open();
            foreach (var item in items)
            {

                param.Value = item.ToString();
                cmd.Parameters.Add(param);
                cmd.Connection = con;
                int n = cmd.ExecuteNonQuery();
                if (n > 0)
                    Console.WriteLine("Price Updated Successfully");
                else
                    Console.WriteLine("Failed");
                
            }
            con.Close();
            //foreach(var item in items)
            //{
            //    Console.WriteLine(string.Join(", ", item));
            //}
            Console.ReadKey();
        }
 

匿名

活跃的成员
已加入
2020年9月29日
留言内容
38
编程经验
Beginner
在最后的代码中,在循环内执行Parameters.Add(第18行)。在循环外执行。
现在,我没有收到任何异常,但是失败了。

C#:
con = new SqlConnection(connection);
            SqlCommand cmd = new SqlCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "sp_updateItems";
            SqlParameter param = new SqlParameter();
            param.ParameterName = "@itemnumber";
            cmd.Parameters.Add(param);
            con.Open();
            foreach (var item in items)
            {

                param.Value = item.ToString();
                
                cmd.Connection = con;
                int n = cmd.ExecuteNonQuery();
                if (n > 0)
                    Console.WriteLine("Price Updated Successfully");
                else
                    Console.WriteLine("Failed");
                
            }
            con.Close();
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,501
地点
弗吉尼亚州切萨皮克
编程经验
10+
什么是失败的?我们不是千里眼。我们也不隶属于5Eyes,也没有黑客工具来监视您在计算机上的工作。
 

匿名

活跃的成员
已加入
2020年9月29日
留言内容
38
编程经验
Beginner
什么是失败的?我们不是千里眼。我们也不隶属于5Eyes,也没有黑客工具来监视您在计算机上的工作。
其实我也不确定什么是失败,为什么失败。我调试了,控件转到了console.writeline("Failed") .
存储过程正常工作。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,501
地点
弗吉尼亚州切萨皮克
编程经验
10+
在那种情况下为0,仅表示没有行被更新。很可能是因为您要更新的表中没有匹配的项目号。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,501
地点
弗吉尼亚州切萨皮克
编程经验
10+
您的存储过程仅查看"station"表。您的商品编号是来自同一张桌子还是其他桌子?
 

匿名

活跃的成员
已加入
2020年9月29日
留言内容
38
编程经验
Beginner
You should also configure the SqlParameter to match the SqlDbType and Size of SP's parameter that is varchar(20).
我相信问题出在这里的foreach循环中。不知道这是否是引起问题的原因。

C#:
  foreach (var item in items)
            {

                param.Value = item.ToString();
               
                cmd.Connection = con;
                int n = cmd.ExecuteNonQuery();
                if (n > 0)
                    Console.WriteLine("Price Updated Successfully");
                else
                    Console.WriteLine("Failed");
               
            }

而不是一个,它一次要拿两个物品。 var项由一次迭代中的count 2组成。


1602925019217.png
 

匿名

活跃的成员
已加入
2020年9月29日
留言内容
38
编程经验
Beginner
您的存储过程仅查看"station"表。您的商品编号是来自同一张桌子还是其他桌子?
项目来自同一张桌子。
我正在使用的Linq将项目存储在一个组中,在索引0,它有2个项目,在索引1,它有6个项目。我相信这是造成问题的原因。如何简单地将所有项目依次存储在列表中?
1602925569009.png
 

匿名

活跃的成员
已加入
2020年9月29日
留言内容
38
编程经验
Beginner
这与其他线程有关 无法隐式转换类型错误
如果您不想分组,为什么要分组?
是的,这是相关的,但是我已经解决了这个问题。我正在使用linq获取帐号及其对应项的列表。我正在获取帐号,因为该帐号将用于其他目的。我正在将该列表传递给updateprice函数。现在,我只想从该列表中提取项目编号,并将其作为参数传递给存储过程。
 
Last edited:
最佳 底部