15

变量名称“@LockState”已被声明。变量名称在查询批处理或存储过程中必须是唯一的。

当我在下面执行此代码时,第二个@LockState 上的 sql 参数出现上述错误。

private void btn_lock2_Click(object sender, EventArgs e)
{
  rwd.command = new SqlCommand();
  rwd.command.Connection = rwd.connection;

  try
  {
    if ((txt2.Text == "")| (txt_desc2.Text == ""))
      appMessages.unCompleteFields();
    else
    {
      long from = long.Parse(this.txt2.Text);
      long to = long.Parse(this.txt3.Text);
      if (from <= to)
      {
        for (long counter = from; counter <= to; counter++) 
        {
          string upd = "update card set LockState=@lockstate,
          card_descr=@card_descr where [cardNumber] = N'{0}'";
          rwd.command.CommandText = upd;
          rwd.command.Parameters.Add(new SqlParameter("@LockState",
          SqlDbType.NVarChar)).Value =1;
          rwd.command.Parameters.Add(new SqlParameter("@card_descr",
          SqlDbType.NVarChar)).Value = txt_desc2.Text;
          rwd.connection.Open();
          rwd.command.ExecuteScalar();
          rwd.connection.Close();
        }
      appMessages.successfulyUpdated();
      }
      else
      {
        appMessages.unsuccessfulyUpdated();
      }
      this.txt1.Text = "";
      this.txt2.Text = "";
    }
  }
  catch (Exception exp) { throw exp; }
  }
}
4

6 回答 6

24

您在循环的每次迭代中多次添加相同的参数。

rwd.command.Parameters.Clear()在每次循环迭代后添加:

for (long counter = from; counter <= to; counter++)
{
    rwd.command.Parameters.Clear();

    string upd = "update card set LockState=@lockstate, card_descr=@card_descr where [cardNumber] = N'{0}'";
    rwd.command.CommandText = upd;
    rwd.command.Parameters.Add(new SqlParameter("@LockState",
    SqlDbType.NVarChar)).Value =1;
    rwd.command.Parameters.Add(new SqlParameter("@card_descr",
    SqlDbType.NVarChar)).Value = txt_desc2.Text;
    rwd.connection.Open();
    rwd.command.ExecuteScalar();
    rwd.connection.Close();
}

或在循环前添加参数:

rwd.command.Parameters.Add(new SqlParameter("@LockState", SqlDbType.NVarChar));
rwd.command.Parameters.Add(new SqlParameter("@card_descr", SqlDbType.NVarChar));

然后在循环中:

for (long counter = from; counter <= to; counter++)
{
    string upd = "update card set LockState=@lockstate,
    card_descr=@card_descr where [cardNumber] = N'{0}'";
    rwd.command.CommandText = upd;

    rwd.command.Parameters["@LockState"].Value =1;
    rwd.command.Parameters["@card_descr"].Value = txt_desc2.Text;

    rwd.connection.Open();
    rwd.command.ExecuteScalar();
    rwd.connection.Close();
}
于 2013-10-23T07:33:53.117 回答
18

因为您在每次迭代中共享命令,所以在循环开始时清除参数。

for (long counter = from; counter <= to; counter++) 
{
  rwd.command.Parameters.Clear();

但我只会通过在循环之前定义它来设置循环中的值,如下所示

rwd.command.Parameters.Add("@LockState",SqlDbType.NVarChar);
rwd.command.Parameters.Add("@card_descr",SqlDbType.NVarChar);

for (long counter = from; counter <= to; counter++) 
{
    rwd.command.Parameters["@LockState"].Value = 1;
    rwd.command.Parameters["@card_descr"].Value = txt_desc2.Text;
    // ...
}

边注:

你有[cardNumber] = N'{0}'"但从未为此设定价值。你最好也使用参数cardNumber

于 2013-10-23T07:33:12.987 回答
3

使用 rwd.command.ExecuteScalar(); rwd.command.Parameters.clear();

于 2018-06-07T23:37:06.350 回答
1

我的答案基本上是对其他两个现有答案(来自@gzaxx 和@Damith)的扩展,它们都是正确的。
您确实SqlCommand在每次循环迭代中使用相同的实例,因此您不必(也不应该)在循环中执行任何初始化操作。
其他人已经写过的是,在循环中添加参数的定义是您的问题的原因,因为您试图在循环迭代时多次定义每个参数。
我认为您还应该考虑的是将其他代码移出循环,这基本上意味着将其从循环内部删除:

string upd = "update card set LockState=@lockstate,
card_descr=@card_descr where [cardNumber] = N'{0}'";
rwd.command.CommandText = up
rwd.command.Parameters.Add(new SqlParameter("@LockState", SqlDbType.NVarChar)).Value =1;
rwd.command.Parameters.Add(new SqlParameter("@card_descr", SqlDbType.NVarChar)).Value = txt_desc2.Text;
rwd.connection.Open();

并将其等效项放在循环之前:

string upd = "update card set LockState=@lockstate,
card_descr=@card_descr where [cardNumber] = N'{0}'";
rwd.command.CommandText = up
SqlParameter lockStateParam = rwd.command.Parameters.Add("@LockState",SqlDbType.NVarChar);
SqlParameter cardDescrParam = rwd.command.Parameters.Add("@card_descr",SqlDbType.NVarChar);
rwd.connection.Open();

您还需要替换设置参数值的方式,将其放在循环中,而不是删除的代码:

lockStateParam.Value = 1;
cardDescrParam.Value = txt_desc2.Text;

当我们将打开连接移出循环时,我们还需要将连接关闭操作移出循环,所以这条指令出去了:

rwd.connection.Close();

整个操作给了我们这个代码块:

string upd = "update card set LockState=@lockstate,
card_descr=@card_descr where [cardNumber] = N'{0}'";
rwd.command.CommandText = up
SqlParameter lockStateParam = rwd.command.Parameters.Add("@LockState",SqlDbType.NVarChar);
SqlParameter cardDescrParam = rwd.command.Parameters.Add("@card_descr",SqlDbType.NVarChar);
rwd.connection.Open();
for (long counter = from; counter <= to; counter++) 
{
  lockStateParam.Value = 1;
  cardDescrParam.Value = txt_desc2.Text;
  rwd.command.ExecuteScalar();
}
rwd.connection.Close();

当进一步看这个时,我发现每次迭代实际上都使用相同的参数值,所以 - 如果它不是简化 StackOverflow 代码的结果 - 这意味着你基本上一遍又一遍地执行相同的更新.
我假设它实际上是一个简化的代码,因为(正如@Damith 指出的那样)您似乎正在按cardNumber列过滤更新的行。看起来有点奇怪的是,您显然是在使用字符串格式来用{0}文本替换占位符。如果是这样,那么您必须CommandText在循环内设置属性,但我宁愿考虑执行@Damith 建议的操作,因此为此添加第三个命令参数。

附带说明:如果提供的答案对您有用(并且基本上所有给出的答案都应该),请考虑接受其中一个(可能是此处出现的第一个)。

于 2016-01-28T20:02:10.587 回答
1

由于您在循环的最顶部使用循环命令(foreach、for 等...),因此添加一个

rwd.Parameters.Clear();

这将在每次迭代时清除参数然后解决问题,我有同样的错误,这解决了它。

于 2021-07-08T00:30:33.687 回答
0

rwd.Parameters.Clear();进入循环,它解决了问题。

于 2020-08-25T13:00:01.960 回答