【问题标题】:how to handle the parameterized query expects the parameter which was not supplied如何处理参数化查询需要未提供的参数
【发布时间】:2016-08-18 18:38:13
【问题描述】:

我在单击按钮时插入数据。我正在尝试处理该字段的异常。我的代码是:

try
        {
            con.Open();
            SqlCommand cmd = new SqlCommand();
            cmd.CommandText = "INSERT INTO omotnica (id,name,date,number)" +
                                    "VALUES(@id,@naziv_predmeta,@date,@number)";

            cmd.Parameters.Add("@id", SqlDbType.Int).Value = idInt;
            cmd.Parameters.Add("@name", SqlDbType.NVarChar, 300).Value = this.textBoxName.Text;
            try
            {
                DateTime datt = DateTime.Parse(textBoxDatumUpisa.Text);
                textBoxDatumUpisa.Text = datt.ToString("d/M/yyyy");
                cmd.Parameters.Add("@date", SqlDbType.DateTime).Value = datt;
            }
            catch (FormatException)
            {
                MessageBox.Show("Date must be dd/MM/yyyy"); 
            }
            try
            {
                cmd.Parameters.Add("@number", SqlDbType.Int).Value = Convert.ToInt32(textBoxNumber.Text);

            }
            catch (SqlException e) when (e.Number == 8178)
            {
                MessageBox.Show("U must enter something");
            }
            catch (FormatException)
            {
                MessageBox.Show("It must be an integer");
            }

            con.Close();
             MessageBox.Show("Saved!");

        }
        catch (Exception ex)
        {
            MessageBox.Show(" error" + ex.Message + ex.Source );

        }try
        {
            con.Open();
            SqlCommand cmd = new SqlCommand();
            cmd.CommandText = "INSERT INTO omotnica (id,name,date,number)" +
                                    "VALUES(@id,@naziv_predmeta,@date,@number)";

            cmd.Parameters.Add("@id", SqlDbType.Int).Value = idInt;
            cmd.Parameters.Add("@name", SqlDbType.NVarChar, 300).Value = this.textBoxName.Text;
            try
            {
                DateTime datt = DateTime.Parse(textBoxDatumUpisa.Text);
                textBoxDatumUpisa.Text = datt.ToString("d/M/yyyy");
                cmd.Parameters.Add("@date", SqlDbType.DateTime).Value = datt;
            }
            catch (FormatException)
            {
                MessageBox.Show("Date must be dd/MM/yyyy"); 
            }
            try
            {
                cmd.Parameters.Add("@number", SqlDbType.Int).Value = Convert.ToInt32(textBoxNumber.Text);

            }
            catch (SqlException e) when (e.Number == 8178)
            {
                MessageBox.Show("U must enter something");
            }
            catch (FormatException)
            {
                MessageBox.Show("It must be an integer");
            }

            con.Close();
             MessageBox.Show("Saved!");

        }
        catch (Exception ex)
        {
            MessageBox.Show(" error" + ex.Message + ex.Source );

        }

当我在 textBoxNumber 中输入一些字符串时,它会触发一个 FormatException 以及一个异常,他的参数化查询需要未提供的参数。当我将 textBox 留空时,它会触发参数化查询需要未提供的参数. 如何改变它?我不是用 SQLException catch 覆盖了那个异常吗? 我需要它在消息框为空或文本框内不是整数时触发消息框。

【问题讨论】:

    标签: c# exception-handling


    【解决方案1】:

    Convert.ToInt32(String.Empty) 将引发 FormatException,因为它无法将空字符串解析为 Int32 值。

    将无效字符串转换为 Int32 会引发 FormatException,但也会引发 SQLException,因为转换失败以及参数化查询,因为它需要 Int32。

    您可以捕获 System.Exception 并打开可能的错误,而不是尝试捕获两个异常:

    catch (Exception ex)            
    {                
        if (ex is FormatException)
        {
            if (string.IsNullOrEmpty(this.textboxName.Text){ 
                MessageBox.Show("U must enter something");
            } else {
                MessageBox.Show("It must be an integer");
            }
            return; 
         } 
         else if (ex is SqlException) {
            MessageBox.Show(ex.Message);
            return;
         }
       throw;
    }
    

    【讨论】:

    • 在出现异常之前进行验证怎么样?
    • 这也是一个解决方案。我只是在澄清为什么他的代码没有按预期工作以及处理多个异常的另一种方法......但我也会验证文本框首先留下异常来处理更复杂的事情,比如 SQLException
    【解决方案2】:

    只需添加: if(textbox.Text == string.Empty) return; 在 Click 事件开始时不会发生这种情况。 与其捕获这么多异常并显示消息框,不如添加 ifconditions 并仅处理应该发生的异常。

    如果您想接收int 输入,请使用numbericUpDown

    【讨论】:

      【解决方案3】:

      您可以安全地尝试转换而不会出现这样的异常

      int num;
      if (!Int32.TryParse(textBoxNumber.Text, out num)) {
          MessageBox.Show("It must be an integer");
          return;
      }
      

      对于可能为空的文本列

      object textValue = String.IsNullOrWhiteSpace(textBoxName.Text)
          ? (object)textBoxName.Text
          : (object)DBNull.Value;
      

      请注意,您必须传递DBNull.Value 而不仅仅是null 作为参数,否则该参数将被视为丢失。

      如果您想显示错误消息:

      if(String.IsNullOrWhiteSpace(textBoxName.Text)) {
          MessageBox.Show("It must be an integer");
          return;
      }
      

      但是代码会变得非常混乱,如果您尝试同时转换文本框值、显示错误消息和构造 SQL 语句。

      而是为值创建一个类

      class Omotnica 
      {
          public int ID { get; set; }
          public string Name { get; set; }
          public DateTime Date { get; set; }
          public int Number { get; set; }
      }
      

      并在第一步中将值放入此类。这也可以通过object data binding 完成。这将为您完成所有转换!

      然后设置 SQL 命令会容易得多。

      如果您仍想手动处理文本框值,您可以为此创建一个方法

      private Omotnica GetValues()
      {
          var o = new Omotnica();
          if (!Int32.TryParse(textBoxNumber.Text, out o.Number)) {
              return null;
          }
      
          if(String.IsNullOrWhiteSpace(textBoxName.Text)) {
              return null;
          }
          o.Name = textBoxName.Text;
      
          ... and so on
      }
      

      然后你可以像这样清理 SQL 部分

      Omotnica o = GetValues();
      if (o == null) {
          MessageBox.Show("Please enter something for number, name, ...");
      } else {
          SqlCommand cmd = new SqlCommand();
          cmd.CommandText = "INSERT INTO omotnica (id,name,date,number) VALUES (@id,...";
          cmd.Parameters.Add("@id", SqlDbType.Int).Value = o.ID;
          cmd.Parameters.Add("@name", SqlDbType.NVarChar, 300).Value = o.Name;
          ...
      }
      

      看起来更整洁了,不是吗?

      【讨论】:

      • 我不想传递一个dbnull.value。我希望它显示一个消息框,让用户更正字段,然后插入它
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-20
      • 2016-04-16
      • 1970-01-01
      相关资源
      最近更新 更多