【问题标题】:How to reuse SqlCommand parameter through every iteration?如何在每次迭代中重用 SqlCommand 参数?
【发布时间】:2012-08-19 11:20:09
【问题描述】:

我想为我的数据库实现一个简单的删除按钮。事件方法看起来像这样:

private void btnDeleteUser_Click(object sender, EventArgs e)
{
    if (MessageBox.Show("Are you sure?", "delete users",MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
    {
        command = new SqlCommand();
        try
        {
            User.connection.Open();
            command.Connection = User.connection;
            command.CommandText = "DELETE FROM tbl_Users WHERE userID = @id";
            int flag;
            foreach (DataGridViewRow row in dgvUsers.SelectedRows)
            {
                int selectedIndex = row.Index;
                int rowUserID = int.Parse(dgvUsers[0,selectedIndex].Value.ToString());

                command.Parameters.AddWithValue("@id", rowUserID);
                flag = command.ExecuteNonQuery();
                if (flag == 1) { MessageBox.Show("Success!"); }

                dgvUsers.Rows.Remove(row);
            }
        }
        catch (SqlException ex)
        {
            MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        finally
        {
            if (ConnectionState.Open.Equals(User.connection.State)) 
               User.connection.Close();
        }
    }
    else
    {
        return;
    }
}

但我收到此消息:

变量@id 已被声明。变量名在内部必须是唯一的 查询批处理或存储过程。

有没有办法重用这个变量?

【问题讨论】:

    标签: c# sql-server ado.net


    【解决方案1】:

    错误是因为您在循环的每次迭代中一次又一次地添加相同的参数。

    我会将该代码移动到一个单独的方法中,以便我可以根据需要从多个地方调用它。

    public bool DeleteUser(int userId)
    {
        string connString = "your connectionstring";
        try
        {
          using (var conn = new SqlConnection(connString))
          {
            using (var cmd = new SqlCommand())
            {
                cmd.Connection = conn;
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = "DELETE FROM tbl_Users WHERE userID = @id";
                cmd.Parameters.AddWithValue("@id", userId);
                conn.Open();
                cmd.ExecuteNonQuery();
                return true;
            }
          }
        }
        catch(Exception ex)
        {
          //Log the Error here for Debugging
          return false;
        }
    
    }
    

    那就这样称呼吧

     foreach (DataGridViewRow row in dgvUsers.SelectedRows)
     {
       int selectedIndex = row.Index;
       if(dgvUsers[0,selectedIndex]!=null)
       {
         int rowUserID = int.Parse(dgvUsers[0,selectedIndex].Value.ToString());
         var result=DeleteUser(rowUserID)
       }
       else
       {
          //Not able to get the ID. Show error message to user
       } 
     }
    

    【讨论】:

      【解决方案2】:

      Parameters.AddWithValue 向命令添加一个新参数。由于您是在具有相同名称的循环中执行此操作,因此您会收到异常“变量名称必须是唯一的”

      所以你只需要一个参数,在循环之前添加它,在循环中只改变它的值。

      command.CommandText = "DELETE FROM tbl_Users WHERE userID = @id";
      command.Parameters.Add("@id", SqlDbType.Int);
      int flag;
      foreach (DataGridViewRow row in dgvUsers.SelectedRows)
      {
          int selectedIndex = row.Index;
          int rowUserID = int.Parse(dgvUsers[0,selectedIndex].Value.ToString());
          command.Parameters["@id"].Value = rowUserID;
          // ...
      }
      

      另一种方法是先使用command.Parameters.Clear();。然后您也可以在循环中添加参数,而无需两次创建相同的参数。

      【讨论】:

        【解决方案3】:

        而不是:

        command.Parameters.AddWithValue("@id", rowUserID);
        

        使用类似的东西:

        System.Data.SqlClient.SqlParameter p = new System.Data.SqlClient.SqlParameter();
        

        在 foreach 之外,只需在循环内手动设置:

        p.ParameterName = "@ID";
        p.Value = rowUserID;
        

        【讨论】:

          【解决方案4】:

          我会用这个:

          public static class DbExtensions
          {
              public static void AddParameter(SQLiteCommand command, string name, DbType type, object value)
              {
                  var param = new SQLiteParameter(name, type);
                  param.Value = value;
                  command.Parameters.Add(param);
              }
          }
          

          然后,调用它:

          DbExtensions.AddParameter(command, "@" + fieldOfSearch[i], DbType.String, value[i]);
          

          【讨论】:

            猜你喜欢
            • 2015-08-30
            • 2019-02-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多