簡體   English   中英

在 C# 程序中將數據類型 varchar 轉換為數字時出錯

[英]Error converting data type varchar to numeric in c# program

請幫助我,這是我在 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;
        }                        
    }

編輯:下面的評論非常正確,直接的問題是您在嘗試放入contactno numeric(18, 0)字段中的數據周圍有單引號,它告訴 SQL 將該值解釋為 varchar。

"','" + txtcont.Text + "','"更改為"'," + txtcont.Text + ",'" (即刪除文本框值兩邊的單引號)並對任何內容執行相同操作其他數字字段。

但是,正如其他回復中提到的, 從安全的角度來看,不推薦這種將 sql 命令字符串連接在一起的一般方法。 首選選項是使用參數化查詢

使用參數化查詢還可以更輕松地處理任何可為 null 的字段, 如本例所示

(編輯以更正答案以回應 Steffen 的評論)

你為什么不使用參數? 它可以防止您的代碼受到 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);
        }
    }
}

您直接將控件的文本值存儲在數字字段(contactno、pf_acc_no 和 basic_sal)中。 這些值真的是數值的 sql 字符串表示嗎?

我會嘗試將它們轉換為數值

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

然后,在 sql 字符串中使用dValue.ToString()或特殊的專用方法轉換為它們的 sql 字符串表示。

根據您的表結構,有 3 個字段是數字數據類型。 它們是 - contactnopf_acc_nobasic_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 ,如此處所示 - 將 Null 值分配給 DataTable 中的整數列

構造這樣的查詢容易出現SqlInjection ,建議改用參數化查詢。

實際上,您的代碼很容易受到 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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM