SqlCommmand参数不被添加到UPDATE语句中(C#,MVC)
SqlCommmand参数不被添加到UPDATE语句中(C#,MVC)
如果你看一下被注释掉的代码,我可以很容易地通过直接将用户输入添加到查询中使其正常工作,但是当我尝试将其参数化时,没有任何值被添加到参数中...
这段代码会抛出一个错误
必须定义表变量@formTable
但问题不仅仅是表变量没有被添加,所有的值都没有被添加(通过将表名变量替换为静态文本进行验证)。
在这个项目中,我有很多结构完全相同的插入语句,它们工作得非常完美。我在这里做错了什么?
string constr = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString; using (SqlConnection con = new SqlConnection(constr)) { //string query = "UPDATE " + s.formTable + " SET " + s.column + " = '" + s.cellValue + "' WHERE MasterID = '" + s.id + "'"; string query = "UPDATE @formTable SET @column = @cellValue WHERE MasterID = @id;"; using (SqlCommand cmd = new SqlCommand(query)) { //SqlParameter param = new SqlParameter("@formTable", s.formTable); //cmd.Parameters.Add(param); cmd.Parameters.AddWithValue("@formTable", s.formTable); cmd.Parameters.AddWithValue("@column", s.column); cmd.Parameters.AddWithValue("@cellValue", s.cellValue.ToString()); cmd.Parameters.AddWithValue("@id", s.id.ToString()); cmd.Connection = con; con.Open(); cmd.ExecuteNonQuery(); con.Close(); } }
问题的出现原因是在使用SqlParameter时,参数只能用于值,而不能用于对象标识符(如表名、列名等)。因此,现有的参数和
是无效的。
解决方法是使用字符串拼接来动态设置表名和列名。但是,这并不意味着存在SQL注入的风险。只需要对用户输入进行验证,确保其值在一组已知的值范围内,并将已知的值用于拼接。
例如,假设有一个包含所有表名的List<string>
。如果表名不会变化,可以将其硬编码;如果表名可能会变化,可以通过查询数据库中的系统/模式表来获取表名并填充该列表。
当用户输入一个表名时,检查其是否在列表中。如果存在,使用列表中相应的值。如果不存在,则处理错误条件(例如向用户显示一条消息)。因此,即使使用了字符串拼接,实际上并没有将用户输入直接插入到字符串中。只是将已知的好值拼接在一起,与现有的字符串字面值没有任何区别。