0

我的代码:

    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 是一个字符串)

如何通过输入字符串来选择列?

4

4 回答 4

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 注入攻击。如果列名确实来自用户的输入,您可以根据可用表列的列表验证字符串,这可以静态生成,也可以在运行时检查表的结构。

于 2013-05-30T12:06:56.977 回答
1

您可以动态构建 SQL 查询,而不是将列名作为参数传递。

于 2013-05-30T12:06:50.723 回答
1

不能使用列名作为参数;您应该考虑以这种方式构建查询:

SqlCommand command = 
      new SqlCommand(
         String.Format(@"SELECT min(Score) 
                         FROM MenAthletics WHERE [{0}] < @result;",     
                         sportEvent), 
                      connect);
command.Parameters.AddWithValue("@result", result);

这种 sql 称为“动态 sql”,可以成为动态构建查询的有效方式。

但是,也有陷阱。除了验证用户输入之外,还要确保您连接到数据库的用户只有足够的权限来执行您想要执行的操作。

另一种不太优雅但可以直接放入存储过程的方法是使用 CASE 语句;

例如:

SELECT min(Score)
FROM MenAthletics 
WHERE 
    CASE 
      WHEN @sportEvent = 'SomeColumnName' THEN SomeColumnName
      WHEN @sportEvent = 'SomeColumnName2' THEN SomeColumnName2
    END < @result;

在大型表上创建和维护都非常繁琐。优点是查询不是动态的。

于 2013-05-30T12:08:15.843 回答
0

这是因为sportEvent作为参数传递的字符串中的值与数据库表中存在的实际列不匹配。

确保它们都匹配,然后只有这个错误才会消失。

否则不要将表的列名作为参数传递,直接写在查询中,并让它的列值作为参数。

希望能帮助到你。

于 2013-05-30T12:07:00.197 回答