我的代码:
SqlCommand command = new SqlCommand("SELECT min(Score) FROM MenAthletics WHERE [(@sportevent)] < (@result);", connect);
command.Parameters.AddWithValue("@sportevent", sportEvent);
command.Parameters.AddWithValue("@result", result);
@result工作正常(只是一个双变量) @sportevent不起作用(错误:无效的列名)(sportEvent是一个字符串)
如何通过输入字符串来选择列?
答案 0 :(得分:4)
您可以在SQL语句中参数化值,但不能参数化列或表名。您需要更改SQL字符串本身中的列名称,例如,使用string.Format
:
SqlCommand command = new SqlCommand(
string.Format("SELECT min(Score) FROM MenAthletics WHERE [{0}] < (@result);", sportEvent)
, connect
);
command.Parameters.AddWithValue("@result", result);
确保列名不是来自用户的输入,否则您将打开代码进行SQL注入攻击。如果列名称确实来自用户的输入,则可以根据可用表列的列表验证字符串,这些列可以静态生成,也可以在运行时检查表的结构。
答案 1 :(得分:1)
您可以动态构建SQL查询,而不是将列名作为参数传递。
答案 2 :(得分:1)
您不能使用列名作为参数;您应该考虑以这种方式构建查询:
SqlCommand command =
new SqlCommand(
String.Format(@"SELECT min(Score)
FROM MenAthletics WHERE [{0}] < @result;",
sportEvent),
connect);
command.Parameters.AddWithValue("@result", result);
这种sql称为“动态sql”,可以是动态构建查询的有效方法。
但是,有pitfalls。除了验证用户输入之外,还要确保您连接到数据库的用户只有足够的权限来执行您想要执行的操作。
另一种不太优雅但可以直接放入存储过程的方法是使用CASE语句;
例如:
SELECT min(Score)
FROM MenAthletics
WHERE
CASE
WHEN @sportEvent = 'SomeColumnName' THEN SomeColumnName
WHEN @sportEvent = 'SomeColumnName2' THEN SomeColumnName2
END < @result;
这对于在大型表上创建和维护都非常繁琐。优点是查询不是动态的。
答案 3 :(得分:0)
这是因为您作为参数传递的sportEvent
字符串中的值与数据库表中存在的实际列不匹配。
确保它们匹配,然后才会出现此错误。
否则不要将表的列名作为参数传递,直接将其写入查询并让其列值为参数。
希望它有所帮助。