SqlParameterCollection只接受非null的SqlParameter类型对象,而不接受DBNull对象

时间:2013-08-25 03:26:22

标签: c# sql-server

每当我在文本框中输入任何内容或空值时,都会出现错误。我的代码是这样的:

 SqlCommand cmd = con.CreateCommand();
 cmd.CommandText = "INSERT INTO Records 
                   ([Student ID], [First Name], [Last Name], [Middle Initial], 
                     Gender, Address, Status, Year, Email, Course, 
                    [Contact Number]) 
                    VALUES (@StudentID, @FirstName, @LastName , @MiddleInitial, 
                            @Gender, @Address, @Status, @Year, @Email, @Course, 
                            @ContactNumber)";

   SqlParameter p1 = new SqlParameter("@StudentID", SqlDbType.NChar);
   p1.Value = textBox1.Text;
   cmd.Parameters.Add(p1);
   SqlParameter p2 = new SqlParameter("@FirstName", SqlDbType.NVarChar);
   p2.Value = textBox2.Text;
   cmd.Parameters.Add(p2);
   SqlParameter p3 = new SqlParameter("@LastName", SqlDbType.NVarChar);
   p3.Value = textBox3.Text;
   cmd.Parameters.Add(p3);
   SqlParameter p4 = new SqlParameter("@MiddleInitial", SqlDbType.NChar);
   p4.Value = comboBox1.Text;
   cmd.Parameters.Add(p4);
   SqlParameter p5 = new SqlParameter("@Gender", SqlDbType.NChar);
   p5.Value = comboBox2.Text;
   cmd.Parameters.Add(p5);
   SqlParameter p6 = new SqlParameter("@Address", SqlDbType.VarChar);
   p6.Value = textBox4.Text;
   cmd.Parameters.Add(p6);
   SqlParameter p7 = new SqlParameter("@Status", SqlDbType.NChar);
   p7.Value = comboBox3.Text;
   cmd.Parameters.Add(p7);
   SqlParameter p8 = new SqlParameter("@Year", SqlDbType.VarChar);
   p8.Value = comboBox4.Text;
   cmd.Parameters.Add(p8);
   SqlParameter p9 = new SqlParameter("@Email", SqlDbType.VarChar);
   p9.Value = textBox5.Text;
   cmd.Parameters.Add(p9);
   SqlParameter p10 = new SqlParameter("@Course", SqlDbType.VarChar);
   p10.Value = comboBox5.Text;
   cmd.Parameters.Add(p10);
   SqlParameter p11 = new SqlParameter("@ContactNumber", SqlDbType.VarChar);
   p11.Value = textBox6.Text;
   cmd.Parameters.Add(p11);

   textBox1.Text = "";
   textBox2.Text = "";
   textBox3.Text = "";
   textBox4.Text = "";
   textBox5.Text = "";
   textBox6.Text = "";
   comboBox1.Text = "";
   comboBox2.Text = "";
   comboBox3.Text = "";
   comboBox4.Text = "";
   comboBox5.Text = "";
   if (cmd.Parameters.Contains(System.DBNull.Value))
   {
       MessageBox.Show("Please complete the fields", "Information...", 
                       MessageBoxButtons.OK, MessageBoxIcon.Warning, 
                       MessageBoxDefaultButton.Button1);
    }
    else
    {
       MessageBox.Show("Data Inserted!", "Information ... ", 
                       MessageBoxButtons.OK, MessageBoxIcon.Information, 
                       MessageBoxDefaultButton.Button1);
    }
    cmd.ExecuteNonQuery();
    con.Close();

错误已开启:

if(cmd.Parameters.Contains(System.DBNull.Value))

我正在使用SQL Server和C#。

4 个答案:

答案 0 :(得分:1)

SqlCommand cmd = con.CreateCommand();
cmd.CommandText = "INSERT INTO Records 
               ([Student ID], [First Name], [Last Name], [Middle Initial], 
                 Gender, Address, Status, Year, Email, Course, 
                [Contact Number]) 
                VALUES (@StudentID, @FirstName, @LastName , @MiddleInitial, 
                        @Gender, @Address, @Status, @Year, @Email, @Course, 
                        @ContactNumber)";
Control[] controls = {textBox1,textBox2, textBox3, textBox4, textBox5, textBox6, comboBox1, comboBox2, comboBox3, comboBox4, comboBox5};
foreach(Control c in controls){
  if(c.Text.Trim() == "") {
      MessageBox.Show("Please complete the fields", "Information...", 
                   MessageBoxButtons.OK, MessageBoxIcon.Warning, 
                   MessageBoxDefaultButton.Button1);
      c.Focus();//Focus it to let user enter some value again.
      return;

  }
}
//Initialize your parameters here
//....
//....
//....

try {
  cmd.ExecuteNonQuery();        
  MessageBox.Show("Data Inserted!", "Information ... ", 
                   MessageBoxButtons.OK, MessageBoxIcon.Information, 
                   MessageBoxDefaultButton.Button1);
  foreach(Control c in controls) c.Text = "";
}catch{}
finally {
  con.Close();
}

答案 1 :(得分:0)

首先,您需要查看任何参数的 value 属性是否为DBNull。您正在尝试检查参数对象本身是否为DBNull,但您应该查看Value属性。你可以这样做:

if ( cmd.Parameters.Any(p => DBNull.Value.Equals(p.Value)) )

其次,文本框控件的.Text属性永远不会为null。在最坏的情况下,它将是空字符串。所以你真正想要的是这样的代码:

if ( cmd.Parameters.Any(p => string.IsNullOrWhiteSpace((string)p.Value)) )

最后,顺便说一下,即使.Text属性可能是null,这也与DBNull不同。它们是两回事。

答案 2 :(得分:0)

清洁有效的方法。将在以后的发展中帮助你。将代码更改为:

  1. 创建一个名为student的类,并在该类中根据需要为FirstNameLastName和其他人创建属性。像这样:

    public class Student
    {
        public int StudentId {get;set;}
        public string FirstName {get;set;}
        public string FirstName {get;set;}
        public string MiddleInitial{get;set;} // upto ContactNumber or as required.
     }
    
  2. 创建一个单独的方法,用于将参数分配给SqlCommand。在这些方法中,如果您需要使用三元运算,也可以进行验证,即:?,

    private void CreateParameterList(ref Student s, ref SqlCommand cmd)
           {
              var parameters = new []
                                   {
                                     new SqlParameter("@FirstName",s.FirstName),
                                     new SqlParameter("@LastName",s.LastName),
                                     :
                                     :
                                      new SqlParameter("@ContactNumber",s.ContactNumber)
                                    }
              cmd.Parameters.AddRange(parameters);
           }
    
  3. 创建一个Save方法并将上面的类作为参数传递。您还可以创建名为Student的单独的部分类,以便使用相同的实例访问成员。调用步骤2中的方法,以便使用参数。

    protected void MySaveFunction(Student s)
    {
        using(SqlConnection con= new SqlConnection(your_Connection_String))
        {
            using(SqlCommmand cmd = new SqlCommand())
            {
                cmd.CommandType = CommandType.Text/StoredProcedure;
                // it depends on what you are using
                cmd.Connection = con;
                cmd.CommandText=Your Query or Name of SP;
                con.Open();
                CreateParameterList(ref s, ref cmd);
                try
                {
                    int i = cmd.ExecuteNonQuery();
                    if(i>0)
                    {
                        //Show Success or return Success
                    }        
                }
                catch(SqlException sqlex)
                {
                    //catch and log exception
                }
                finally
                {  con.Close(); con.Dispose() }
            }
        }
    }
    

答案 3 :(得分:0)

为什么不重新开始并在达到这一点之前做一些适当的验证?如果没有必要,你永远不应该开始创建对象和东西。所以,帮自己一个忙,并在

中添加一个验证方法
private bool IsValid()
{
    return !Controls.OfType<TextBox>().Any(c=> String.IsNullOrEmpty(c.Text));
}

然后在代码之前添加一个调用来构造sqlcommand和参数集合

if(IsValid())
{
    // do you stuff here
}
else
{
   MessageBox.Show("Please complete the fields", "Information...", 
                   MessageBoxButtons.OK, MessageBoxIcon.Warning, 
                   MessageBoxDefaultButton.Button1);
}

请记住,这没有经过测试,我现在没有VS,所有都是手动编写的,因此可能不会以这种方式访问​​Control集合。