向数据库插入数据时遇System.Data.SqlClient.SqlException错误求助
解决SQL插入时的"字符串或二进制数据将被截断"错误
嘿,咱们一步步来解决你遇到的这个问题。首先你看到的System.Data.SqlClient.SqlException异常,提示“字符串或二进制数据将被截断”,这个错误的核心原因很直白:你输入的某个字段内容长度,超过了数据库students表中对应列的定义长度。举个例子,如果数据库里S_username列定义的是varchar(20),但你输入的用户名长度超过20,就会触发这个错误。
另外必须严肃提醒你:你的代码存在严重的SQL注入漏洞!直接把用户输入的文本拼接进SQL语句里,这是非常危险的操作——攻击者可以轻易篡改你的SQL逻辑,甚至删除整个数据库,这绝对是不能忽视的问题。
两步搞定你的问题:
1. 定位并解决字段长度不匹配问题
- 先打开你的SQL Server数据库,查看
students表中每个列的定义(比如S_username是varchar(50)还是nvarchar(30),括号里的数字就是该列允许的最大长度) - 对比你输入的每个文本框内容,比如如果
TxtEmail.Text输入了超过对应列长度的邮箱地址,就会触发错误。你可以临时在代码里加几行输出,快速定位哪个字段出了问题:Console.WriteLine($"用户名长度: {txtuName.Text.Length}"); Console.WriteLine($"邮箱长度: {TxtEmail.Text.Length}"); // 把所有字段都这样输出一遍,对比数据库列的长度 - 解决办法要么是缩短输入的内容,要么如果业务允许的话,修改数据库对应列的长度,放宽限制。
2. 修复SQL注入漏洞,改用参数化查询
这是必须要做的,不仅能彻底解决安全问题,还能避免很多字符串拼接带来的麻烦(比如单引号转义、字段类型不匹配等)。我帮你改写了代码,你可以参考:
// 用参数化SQL替代字符串拼接,更安全也更可靠 string insertSql = @"INSERT INTO students (S_username,S_password,S_f_name,S_m_name,S_l_name,S_father_name,S_mother_name,S_dob,S_gender,S_cast_id,S_religion,S_father_occu,S_mothers_occu,S_annual_income,S_local_add,S_p_address,S_L_pincode,S_p_pincode,S_L_city,S_p_city,S_L_state,S_p_state,S_department,S_semistor,s_mob_no,s_parents_mob_no,s_email,S_aadhar_no) VALUES (@S_username, @S_password, @S_f_name, @S_m_name, @S_l_name, @S_father_name, @S_mother_name, @S_dob, @S_gender, @S_cast_id, @S_religion, @S_father_occu, @S_mothers_occu, @S_annual_income, @S_local_add, @S_p_address, @S_L_pincode, @S_p_pincode, @S_L_city, @S_p_city, @S_L_state, @S_p_state, @S_department, @S_semistor, @s_mob_no, @s_parents_mob_no, @s_email, @S_aadhar_no)"; using (SqlCommand cmd = new SqlCommand(insertSql, con)) { // 逐一添加参数,注意参数的类型和长度要和数据库列的定义匹配 cmd.Parameters.Add("@S_username", SqlDbType.VarChar, 50).Value = txtuName.Text; cmd.Parameters.Add("@S_password", SqlDbType.VarChar, 50).Value = txtpass.Text; cmd.Parameters.Add("@S_f_name", SqlDbType.VarChar, 50).Value = Txtfname.Text; cmd.Parameters.Add("@S_m_name", SqlDbType.VarChar, 50).Value = Txtmname.Text; cmd.Parameters.Add("@S_l_name", SqlDbType.VarChar, 50).Value = Txtlname.Text; cmd.Parameters.Add("@S_father_name", SqlDbType.VarChar, 100).Value = TxtFthname.Text; cmd.Parameters.Add("@S_mother_name", SqlDbType.VarChar, 100).Value = Txtmname.Text; // 处理日期的时候,最好做格式校验,避免输入错误的日期 if (!DateTime.TryParse(TextBox2.Text, out DateTime dob)) { Console.WriteLine("请输入正确的日期格式!"); return; } cmd.Parameters.Add("@S_dob", SqlDbType.Date).Value = dob; cmd.Parameters.Add("@S_gender", SqlDbType.VarChar, 10).Value = DropDownList2.SelectedItem.Value; cmd.Parameters.Add("@S_cast_id", SqlDbType.Int).Value = int.Parse(DropDownList.SelectedItem.Value); cmd.Parameters.Add("@S_religion", SqlDbType.VarChar, 50).Value = txtrel.Text; cmd.Parameters.Add("@S_father_occu", SqlDbType.VarChar, 100).Value = Txtfoccu.Text; cmd.Parameters.Add("@S_mothers_occu", SqlDbType.VarChar, 100).Value = Txtmoccu.Text; cmd.Parameters.Add("@S_annual_income", SqlDbType.Int).Value = int.Parse(DropDownList1.SelectedItem.Value); cmd.Parameters.Add("@S_local_add", SqlDbType.VarChar, 200).Value = Txtlcaladd.Text; cmd.Parameters.Add("@S_p_address", SqlDbType.VarChar, 200).Value = TxtpAdd.Text; cmd.Parameters.Add("@S_L_pincode", SqlDbType.VarChar, 10).Value = Txtzipcode.Text; cmd.Parameters.Add("@S_p_pincode", SqlDbType.VarChar, 10).Value = Txtzipc.Text; cmd.Parameters.Add("@S_L_city", SqlDbType.VarChar, 50).Value = Txtcity.Text; cmd.Parameters.Add("@S_p_city", SqlDbType.VarChar, 50).Value = Textcity.Text; cmd.Parameters.Add("@S_L_state", SqlDbType.VarChar, 50).Value = Txtstate.Text; cmd.Parameters.Add("@S_p_state", SqlDbType.VarChar, 50).Value = Textstate.Text; cmd.Parameters.Add("@S_department", SqlDbType.VarChar, 100).Value = DropDownList3.SelectedItem.Value; cmd.Parameters.Add("@S_semistor", SqlDbType.VarChar, 10).Value = Txtsem.Text; // 手机号、Aadhar号这类长数字,别用int,容易溢出,用long或者存字符串更稳妥 if (!long.TryParse(Txtmb.Text, out long mobNo)) { Console.WriteLine("请输入正确的手机号!"); return; } cmd.Parameters.Add("@s_mob_no", SqlDbType.BigInt).Value = mobNo; if (!long.TryParse(Txtparmb.Text, out long parentMobNo)) { Console.WriteLine("请输入正确的家长手机号!"); return; } cmd.Parameters.Add("@s_parents_mob_no", SqlDbType.BigInt).Value = parentMobNo; cmd.Parameters.Add("@s_email", SqlDbType.VarChar, 100).Value = TxtEmail.Text; if (!long.TryParse(TxtAdhno.Text, out long aadharNo)) { Console.WriteLine("请输入正确的Aadhar号码!"); return; } cmd.Parameters.Add("@S_aadhar_no", SqlDbType.BigInt).Value = aadharNo; con.Open(); cmd.ExecuteNonQuery(); con.Close(); // 清空所有输入框 txtuName.Text = string.Empty; txtpass.Text = string.Empty; Txtfname.Text = string.Empty; Txtmname.Text = string.Empty; Txtlname.Text = string.Empty; TxtFthname.Text = string.Empty; TextBox2.Text = string.Empty; txtrel.Text = string.Empty; Txtfoccu.Text = string.Empty; Txtmoccu.Text = string.Empty; Txtlcaladd.Text = string.Empty; TxtpAdd.Text = string.Empty; Txtzipcode.Text = string.Empty; Txtzipc.Text = string.Empty; Txtcity.Text = string.Empty; Textcity.Text = string.Empty; Txtstate.Text = string.Empty; Textstate.Text = string.Empty; Txtsem.Text = string.Empty; TxtEmail.Text = string.Empty; TxtAdhno.Text = string.Empty; Console.WriteLine("Success"); }
额外小提示:
- 你原来代码里有几行关于
Request.QueryString的代码,看起来和当前的插入逻辑不相关,而且如果是WebForm的话,直接用文本框的值就可以了,不需要从QueryString里取,这部分可以考虑删掉,避免混淆。
内容的提问来源于stack exchange,提问作者Akhil Raj
相关产品推荐
相关产品推荐

