c# - 是否可以在不求助于动态 SQL 的情况下查询用户指定的列名?

标签 c# sql sql-server-2005

我正在尝试实现具有以下签名的 API:

public static List<string> SearchDatabase(
    string column,
    string value);

API 的实现需要构造一个带有 WHERE 子句的 SQL SELECT 查询,该子句使用在 column 参数中指定的列名.

查询:

string query =
    string.Format(
        "SELECT Name, @Column " +
        "FROM Db1 " +
        "INNER JOIN Db2 ON Db1.Id = Db2.Id " +
        "WHERE @Column = @Value");

SQL命令及参数:

SqlCommand selectCmd =
    new SqlCommand(
        query,
        connection);
selectCmd.CommandTimeout = SqlCommandTimeout;
selectCmd.Parameters.AddRange(
    new SqlParameter[]
{
    new SqlParameter("@Column", column),
    new SqlParameter("@Value", value)
});

然后我这样执行:

SqlDataReader sqlDataReader = selectCmd.ExecuteReader();
while (sqlDataReader.Read())
{
    // ...
}

问题是 sqlDataReader 没有返回任何行,所以我没有进入上面的 while 循环。

但是,如果我将上面查询的最后一行更改为:

"WHERE @Column = @Value");

"WHERE Vendor = @Value");

(即,将列名称硬编码为“供应商”)然后它就可以工作了。

我从所做的研究中了解到,不可能将列名作为参数传递,而只能传递我们查询的值。但是,它似乎确实让我在 SELECT 子句中使用了 @Column 参数,而不是 WHERE 子句。

由于 SQL 注入(inject)问题,我不想求助于动态 SQL。还有其他解决方法吗?

最佳答案

不幸的是表名,列名不能参数化。因为你知道表的结构,你可以在这个参数中有一个可能的列名的白名单,然后使用字符串连接来避免 SQL 注入(inject):

"WHERE " + Sanitize(column) + " = @Value");

关于c# - 是否可以在不求助于动态 SQL 的情况下查询用户指定的列名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7441344/

相关文章:

c# - 如何在 C++ 中编写 Jon Skeet 的 Singleton?

mysql - 未找到列 : 1054 Unknown column '` default `' in ' where clause', 查询为 : SELECT `main_table` . * FROM `fastimporter_attributes`

mysql - 形成组元素的扩展组

sql - 删除并重新使用存储过程中的临时表

sql - 尽管已对有序列建立了索引,但为什么我的 SQL Server ORDER BY 仍然很慢?

sql-server - SQL Server 添加列

c# - 循环遍历 checkedListBox 项目而不选择所有项目

c# - WCF 服务 : (413) Request Entity Too Large 返回意外响应

c# - 从数据表导出到 excel 时,如何阻止前导 0 被剥离?

SQL Server 触发器