MSSQL数据库读取字符串出现末尾空格的问题排查及解决
问题:SQL读取字符串末尾出现多余空格,导致判断逻辑异常
我有两个C#程序,一个负责向MSSQL数据库插入数据,另一个负责从数据库读取数据。插入数据时字符串长度正常(例如KNR长度为7),但读取时字符串末尾被添加了空格,长度变为10(如原字符串为“working”,读取后变为“working ”),导致后续判断逻辑异常。
插入数据代码
int k = WNR_KNR[1].Length; int w = WNR_KNR[0].Length; int s = status.Length; SqlConnection con = new SqlConnection(connectionstring); con.Open(); string delete = "DELETE FROM Fertigung.dbo.Box" + boxnumber + "Status"; SqlCommand commanddel = new SqlCommand(delete, con); commanddel.ExecuteNonQuery(); string query = "INSERT INTO Fertigung.dbo.Box" + boxnumber + "Status (WNR,KNR,status) VALUES ('" + WNR_KNR[0] +"','" + WNR_KNR[1] +"','"+status+"')"; SqlCommand cmd = new SqlCommand(query, con); cmd.ExecuteNonQuery(); con.Close();
读取数据代码
string sqlquery = "SELECT KNR, WNR, status FROM Fertigung.dbo.Box" + name + "Status"; SqlCommand com = new SqlCommand(sqlquery, con); SqlDataReader reader = com.ExecuteReader(); while (reader.Read()) { KNR = reader["KNR"].ToString(); WNR = reader["WNR"].ToString(); status = reader["status"].ToString(); int k = KNR.Length; int w = WNR.Length; int s = status.Length; }
原因分析
- 数据库表中
WNR、KNR、status字段类型为CHAR(n):CHAR是固定长度类型,会自动用空格填充到指定的n长度;而VARCHAR是可变长度类型,不会自动补空格。这是读取后字符串带空格的核心原因。 - 插入代码中已确认字符串长度正常,说明问题出在数据库存储环节,而非插入前的数据本身。
解决方法
1. 修改数据库字段类型(优先推荐)
将对应字段从CHAR(n)改为VARCHAR(n)(若需存储多语言字符则用NVARCHAR(n)),这样数据库不会自动填充空格,读取时直接获取原始长度的字符串。
2. 读取时去除末尾空格(临时方案)
如果无法修改数据库结构,可在读取后调用TrimEnd()方法移除末尾空格:
KNR = reader["KNR"].ToString().TrimEnd(); WNR = reader["WNR"].ToString().TrimEnd(); status = reader["status"].ToString().TrimEnd();
注意:若业务允许字符串末尾存在合法空格,请勿使用此方法,避免丢失有效数据。
3. 修复SQL注入风险(重要)
当前代码直接拼接SQL语句,存在严重的SQL注入漏洞,必须改用参数化查询:
插入数据的参数化写法
int k = WNR_KNR[1].Length; int w = WNR_KNR[0].Length; int s = status.Length; using (SqlConnection con = new SqlConnection(connectionstring)) { con.Open(); string delete = "DELETE FROM Fertigung.dbo.Box" + boxnumber + "Status"; using (SqlCommand commanddel = new SqlCommand(delete, con)) { commanddel.ExecuteNonQuery(); } string query = "INSERT INTO Fertigung.dbo.Box" + boxnumber + "Status (WNR,KNR,status) VALUES (@WNR, @KNR, @status)"; using (SqlCommand cmd = new SqlCommand(query, con)) { cmd.Parameters.AddWithValue("@WNR", WNR_KNR[0]); cmd.Parameters.AddWithValue("@KNR", WNR_KNR[1]); cmd.Parameters.AddWithValue("@status", status); cmd.ExecuteNonQuery(); } }
读取数据的安全写法(动态表名需验证)
若name为用户输入,必须先验证是否在合法表名白名单内,避免注入:
// 示例:定义合法表名白名单 var validTableNames = new List<string> { "1", "2", "3" }; // 根据实际业务调整 if (!validTableNames.Contains(name)) { throw new ArgumentException("无效的表名"); } string sqlquery = $"SELECT KNR, WNR, status FROM Fertigung.dbo.Box{name}Status"; using (SqlCommand com = new SqlCommand(sqlquery, con)) { using (SqlDataReader reader = com.ExecuteReader()) { while (reader.Read()) { KNR = reader["KNR"].ToString().TrimEnd(); WNR = reader["WNR"].ToString().TrimEnd(); status = reader["status"].ToString().TrimEnd(); int k = KNR.Length; int w = WNR.Length; int s = status.Length; } } }
内容的提问来源于stack exchange,提问作者user20356767
相关产品推荐
相关产品推荐

