【问题标题】:How to execute stored procedure multiple times in C#如何在C#中多次执行存储过程
【发布时间】:2011-11-15 18:19:37
【问题描述】:

我有一个时间表应用程序,用户可以在其中输入一周中不同日期的进出时间。该表单处理每天的输入/输出,将它们作为参数填充到存储过程中并将它们添加到数据库中。我将如何最有效地完成这项工作?我无权访问数据库,只有存储过程。

这是后面的裸代码,我已经去掉了一些不必要的代码。

SqlConnection conn = new SqlConnection(connString);
conn.Open();
SqlCommand cmd = new SqlCommand("insertINOUT", conn);
cmd.CommandType = CommandType.StoredProcedure;

cmd.Parameters.Add(new SqlParameter("@UserName", user));

for (int j = 0; j < weekDays.Length; j++)
{
    cmd.Parameters.Add(new SqlParameter("@In", in));
    cmd.Parameters.Add(new SqlParameter("@Out", out));
    cmd.ExecuteReader();
}
conn.Close();

如果只有 1 天的进出,则代码有效。如果用户填写多天,我会得到这个错误:参数'@In'被提供了多次。

感谢您的帮助。

【问题讨论】:

  • 这都是因为for 循环中的那些new 语句。您正在尝试为已经存在的东西创建new

标签: c# procedures


【解决方案1】:
SqlConnection conn = new SqlConnection(connString);
conn.Open();
SqlCommand cmd = new SqlCommand("insertINOUT", conn);
cmd.CommandType = CommandType.StoredProcedure;

for (int j = 0; j < weekDays.Length; j++)
{
    **cmd.Parameters.Clear();**
    cmd.Parameters.Add(new SqlParameter("@UserName", user));
    cmd.Parameters.Add(new SqlParameter("@In", in));
    cmd.Parameters.Add(new SqlParameter("@Out", out));
    cmd.ExecuteReader();
}
conn.Close();

(每次迭代都要清除参数。)

【讨论】:

    【解决方案2】:

    另一种选择,您可以更改 SqlCommand 的范围,以便每次都重新创建它。

    SqlConnection conn = new SqlConnection(connString);
    conn.Open();
    
    for (int j = 0; j < weekDays.Length; j++)
    {
        SqlCommand cmd = new SqlCommand("insertINOUT", conn);
        cmd.CommandType = CommandType.StoredProcedure;
    
        cmd.Parameters.Add(new SqlParameter("@UserName", user));
        cmd.Parameters.Add(new SqlParameter("@In", in));
        cmd.Parameters.Add(new SqlParameter("@Out", out));
        cmd.ExecuteReader();
    }
    conn.Close();
    

    似乎有点浪费,但有一些库是这样工作的(想到企业库 DAAB)。

    【讨论】:

      【解决方案3】:
      using (SqlConnection conn ... )
      {
          SqlCommand cmd = ...
          ...
          // Set up the parameter list.
          //   You can use   .AddWithValue   here to add values that don't change in the loop.
          cmd.Parameters.Add("@Username", SqlDbType.VarChar);
          ...
          for (...)
          {
              // Load one set of loopy values.
              cmd.Parameters["@UserId"].Value = user;
              ...
          }
      }
      

      【讨论】:

        【解决方案4】:

        这是因为您试图将相同的参数重新添加到同一个 sqlcommand 对象。为了获得最佳性能,在开始 for 循环之前,打开连接并添加不带值的参数。然后,在您的 for 循环中,您所做的就是设置参数的值,然后执行该过程。无需在循环的每次迭代中重新创建参数本身,您只是白白浪费资源。试试这个:

        string strCon = "Your Connection String Here";
        using (SqlConnection conSQL = new SqlConnection(strCon))
        {
            conSQL.Open();
            using (SqlCommand cmdSQL = new SqlCommand())
            {
                cmdSQL.CommandType = CommandType.StoredProcedure;
                cmdSQL.CommandText = "The Name of Your Stored Procedure Here";
                cmdSQL.Connection = conSQL;
                // I'm just going to assume that the data type for the
                // parameters is nvarchar and that both are input parameters...
                // Just for demonstration purposes
                cmdSQL.Parameters.Add("@In", SqlDbType.NVarChar, 50);
                cmdSQL.Parameters.Add("@Out", SqlDbType.NVarChar, 50);
                for (var j = 0; j <= weekDays.Length - 1; j += 1)
                {
                    cmdSQL.Parameters("@In").Value = strIn;
                    cmdSQL.Parameters("@Out").Value = strOut;
                    // I'm not sure why in your code you put ExecuteReader here.
                    // You don't show that you're using the reader at all, rather
                    // it looks like you are actually just trying to execute the procedure without
                    // using any type of return parameter values or a reader.
                    // So I changed the code here to be what it should be if that is true.
                    cmdSQL.ExecuteNonQuery();
                }
            }
            conSQL.Close();
        }
        

        我知道这个问题已经有好几年了,但我认为仍然会有人搜索这个问题,也许会发现这个答案很有帮助。

        【讨论】:

          【解决方案5】:

          您收到该错误的原因是因为 for 循环多次重新添加参数:

          cmd.Parameters.Add(new SqlParameter("@In", in));
          cmd.Parameters.Add(new SqlParameter("@Out", out));
          

          执行此操作的正确方法是清除 foor 循环最后一行的参数集合,或者简单地检查参数是否已经存在并设置其值,而不是执行 Parameters.Add

          【讨论】:

            【解决方案6】:
            SqlConnection conn = new SqlConnection(connString);
            conn.Open();
            SqlCommand cmd = new SqlCommand("insertINOUT", conn);
            
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(new SqlParameter("@UserName", user));
                for (int j = 0; j < weekDays.Length; j++)
                {
            
            
                    cmd.Parameters.Add(new SqlParameter("@In"+j, in));
                    cmd.Parameters.Add(new SqlParameter("@Out"+j, out));
                    cmd.ExecuteReader();
                }
                conn.Close();
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-12-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多