在c#程序中将数据类型varchar转换为numeric时出错

时间:2016-01-12 07:30:14

标签: c# sql-server

请帮帮我,这是我在sql-server中的数据库表

(empcode    varchar(50)
firstname   varchar(50)
lastname    varchar(50)
gender  varchar(50)
address varchar(50)
contactno   numeric(18, 0)
bloodgroup  varchar(50)
dateofbirth date
country varchar(50)
qid varchar(50)
passportno  varchar(50)
passportexpiredate  date
designation varchar(50)
doj date    
doexpid date
pf_acc_no   numeric(18, 0)  
agreementstartdate  date    
agreementenddate    date    
department  varchar(50) 
basic_sal   numeric(18, 0)  
remarks varchar(50) 
empimage    image)

我试图通过c#windows窗体插入我的数据,但我收到错误为“将数据类型varchar转换为数字时出错。” 以下是我的c#代码

private void button2_Click(object sender, EventArgs e)
    {
        cn.Open();
        if (!empid())
        {
            DialogResult d = new DialogResult();
            d = MessageBox.Show("Do You Declare Yourself All The Information Of This Employee Is Correct To Save?", "Message", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (d == DialogResult.Yes)
            {
                int i = 0;
                SqlCommand cmd = new SqlCommand("INSERT INTO Employee(
     empcode,firstname,lastname,gender,address,contactno,bloodgroup,
    dateofbirth, country,qid,passportno,passportexpiredate,designation,
    doj,doexpid,pf_acc_no, agreementstartdate,agreementenddate,
    department,basic_sal,remarks,empimage) 
    VALUES('" + txtempcode.Text + "','" + txtfrstname.Text + "', 
    '" + txtlstname.Text + "','" + combogender.Text + "','" +
    txtaddr.Text + "','" + txtcont.Text + "','" + txtblodgrp.Text + "', '" + 
    dob.Value.ToString("yyyy/MM/dd") + "' ,'" + txtcountry.Text + "','" + tqid.Text + "','" + 
    txtpassportno.Text + "', '" + passexpdate.Value.ToString("yyyy/MM/dd") + "' ,'" + 
    combodesig.Text + "', '" + doj.Value.ToString("yyyy/MM/dd") + "', '" + doexpqid.Value.ToString("yyyy/MM/dd") + "', '" + 
    txtqibacc.Text + "', '" + agreestartdate.Value.ToString("yyyy/MM/dd") + "','" + agreeenddate.Value.ToString("yyyy/MM/dd") + "' ,'" + combobranch.Text + "','" + txtnetsalary.Text + "','" + txtremark.Text + "',@empimage) ", cn);

                    MemoryStream stream = new MemoryStream();
                    pb1.Image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
                    byte[] pic = stream.ToArray();
                    cmd.Parameters.AddWithValue("@empimage", pic);
                i = cmd.ExecuteNonQuery();

                if (i > 0)
                {
                    MessageBox.Show("Successfully Inserted Employee Record" + i);
                }
                cn.Close();
                showdata();
                clear();
            }
        }
    }

public bool empid()
    {
        using (SqlConnection con = new SqlConnection("Data Source=SAFIYA-PC;Initial Catalog=dbEmployee;User ID=sa;Password=sa$123"))
        {
            con.Open();
            string query = "select empcode from Employee where empcode = '" + txtempcode.Text + "'";
            SqlCommand cmd = new SqlCommand(query, con);
            SqlDataReader dr;
            dr = cmd.ExecuteReader();
            while (dr.Read())
            {
                empCode = dr["empcode"].ToString();
                if (empCode != "0")
                {
                    MessageBox.Show("Id already Existed Please use Another One!!!!!!");
                    return false;
                }
                con.Close();
            }
            return true;
        }                        
    }

5 个答案:

答案 0 :(得分:1)

编辑:下面的评论非常正确,最直接的问题是,您在contactno numeric(18, 0)字段中输入的数据周围有单引号,告诉SQL将该值解释为varchar。< / p>

"','" + txtcont.Text + "','"更改为"'," + txtcont.Text + ",'"(即删除文本框值两侧的单引号)并对其他任何数字字段执行相同操作。

但是,正如其他响应中所提到的,这种将sql命令字符串is not recommended from a security point of view连接在一起的一般方法。首选方案是使用parametrised query

使用参数化查询还可以更轻松地处理任何可以为空的字段as per this example

(为响应Steffen的评论而修改答案)

答案 1 :(得分:1)

为什么不使用参数?它可以防止您的代码进入SQL注入,并且您不必转换值,代码更易读。查看示例(它适用于select语句,但同样适用于insert / update / delete语句):

var connectionString = "some connection string";
using (var connection = new SqlConnection(connectionString)) {
    connection.Open();
    using (var command = new SqlCommand("SELECT * FROM Dogs1 WHERE Name LIKE @Name", connection)) {
        command.Parameters.Add(new SqlParameter("Name", dogName));
        var reader = command.ExecuteReader();
        while (reader.Read()) {
            int weight = reader.GetInt32(0);
            string name = reader.GetString(1);
            string breed = reader.GetString(2);
            Console.WriteLine("Weight = {0}, Name = {1}, Breed = {2}",
            weight,
            name,
            breed);
        }
    }
}

答案 2 :(得分:0)

您直接在数字字段中存储控件的文本值(contactno,pf_acc_no和basic_sal)。值是否真的是数值的sql-string表示?

我会尝试将它们转换为数值

double dValue = 0.0;
double.TryParse(textBox1.Text, out dValue);

然后,在sql字符串中转换为带有dValue.ToString()的sql-string表示或特殊的专用方法。

答案 3 :(得分:0)

根据您的表结构,有3个数字数据类型的字段。这些是 - contactno pf_acc_no basic_sal

这些文件的值分别为txtcont.Texttxtqibacc.Texttxtnetsalary.Text,并且您也将'放在它们周围,这就是为什么它们被视为varchar提交。

在构造sql语句时,您应该将这些字段的值作为数字传递,也就是说没有'标记。因此,只需在这些字段之前和之后删除',您的查询就可以正常运行。

SqlCommand cmd = new SqlCommand("INSERT INTO Employee(
     empcode,firstname,lastname,gender,address,contactno,bloodgroup,
    dateofbirth, country,qid,passportno,passportexpiredate,designation,
    doj,doexpid,pf_acc_no, agreementstartdate,agreementenddate,
    department,basic_sal,remarks,empimage) 
    VALUES('" + txtempcode.Text + "','" + txtfrstname.Text + "', 
    '" + txtlstname.Text + "','" + combogender.Text + "','" +
    txtaddr.Text + "'," + txtcont.Text + ",'" + txtblodgrp.Text + "', '" + 
    dob.Value.ToString("yyyy/MM/dd") + "' ,'" + txtcountry.Text + "','" + tqid.Text + "','" + 
    txtpassportno.Text + "', '" + passexpdate.Value.ToString("yyyy/MM/dd") + "' ,'" + 
    combodesig.Text + "', '" + doj.Value.ToString("yyyy/MM/dd") + "', '" + doexpqid.Value.ToString("yyyy/MM/dd") + "', " + 
    txtqibacc.Text + ", '" + agreestartdate.Value.ToString("yyyy/MM/dd") + "','" + agreeenddate.Value.ToString("yyyy/MM/dd") + "' ,'" + combobranch.Text + "'," + txtnetsalary.Text + ",'" + txtremark.Text + "',@empimage) ", cn);

如果您需要将null传递给这些数字字段,请使用DBNull.Value,如下所示 - Assign Null value to the Integer Column in the DataTable

构建像这样的查询很容易SqlInjection,建议使用参数化查询。

答案 4 :(得分:-1)

实际上,您的代码非常容易受到SQL注入攻击。但我不改变你的编程风格;我只是更改您的插入查询:

SqlCommand cmd = new SqlCommand(@"
    INSERT INTO Employee
        (empcode, firstname, lastname, gender, address, contactno,
         bloodgroup, dateofbirth, country, qid, passportno, passportexpiredate, 
         designation, doj, doexpid, pf_acc_no, agreementstartdate, agreementenddate, 
         department, basic_sal, remarks, empimage) 
    VALUES
        ('" + txtempcode.Text + "',
         '" + txtfrstname.Text + "', 
         '" + txtlstname.Text + "',
         '" + combogender.Text + "',
         '" + txtaddr.Text + "',
         "  + txtcont.Text + ",
         '" + txtblodgrp.Text + "', 
         '" + dob.Value.ToString("yyyy/MM/dd") + "' ,
         '" + txtcountry.Text + "',
         '" + tqid.Text + "',
         "  + txtpassportno.Text + ", 
         '" + passexpdate.Value.ToString("yyyy/MM/dd") + "' ,
         '" + combodesig.Text + "', 
         '" + doj.Value.ToString("yyyy/MM/dd") + "', 
         '" + doexpqid.Value.ToString("yyyy/MM/dd") + "', 
         '" + txtqibacc.Text + "', 
         '" + agreestartdate.Value.ToString("yyyy/MM/dd") + "',
         '" + agreeenddate.Value.ToString("yyyy/MM/dd") + "' ,
         '" + combobranch.Text + "',
         "  + txtnetsalary.Text + ",
         '" + txtremark.Text + "',
         @empimage) ", cn);