使用列名称列表查询SQL表

时间:2014-09-03 10:39:53

标签: c# sql .net sql-server

我有两个问题 1.我有一个字符串列表,它是列名。我如何在SQL查询中使用它? 2.该方法是否容易出现SQL注入?

这就是我现在所拥有的,

List<string> Columnnames = new List<string>();

 cmd = new SqlCommand("Select "+Columnnames+" from test");

5 个答案:

答案 0 :(得分:1)

回答你的问题:

问题1 - 将您的代码更改为:

List<string> Columnnames = new List<string>();

// Code that populates Columnnames here

cmd = new SqlCommand("Select " + string.Join(",", Columnnames) + " from test");

问题2 - 取决于您如何填充Columnnames。如果这是通过网络输入填充,那么是。

答案 1 :(得分:1)

如果列名来自外部源,那么是的,您必须将它们连接到字符串中。理想情况下,您应该使用[ / ],但这只允许带有空格等的列名称 - 它不会改变有关SQL注入的任何内容,是的:允许列名由a指定用户将是SQL注入风险,除非您先将其列入白名单。所以也许:

if(Columnnames.Count == 0) throw new ArgumentException(
    "You need to specify at least one column");

var sql = new StringBuilder("select ");
bool first = true;
foreach(var name in Columnnames) {
    if(!IsKnownColumnName(name)) { // <=== very important test
        throw new ArgumentException("Invalid column name: " + name);
    }
    sql.Append(first ? "[" : ",[").Append(name).Append("]");
    first = false;
}
sql.Append(" from test");
...
cmd.CommandText = sql.ToString();

答案 2 :(得分:0)

您可以将Columnnames的列表转换为逗号分隔的列值。像这样:

string columns = Columnnames.Aggregate((x,y) => x + "," + y);
cmd = new SqlCommand("Select "+columns+" from test");

这种方法很容易被SQL注入,因为有人可以轻松发送像column ;drop database yourDB这样的列名,所以这是一个坏主意。

答案 3 :(得分:0)

首先检查Columnames是否有任何值。 第二个创建一个函数来创建类似dus columna,column SqlCommand应该看起来像这样选择columna,columb from test;

答案 4 :(得分:0)

您应该将列名连接到查询,以便每个列名用下一个用逗号分隔,例如(伪)

define sql = "SELECT "

for columnName in columnNames:
    concatenate sql,columnName

    if columnName is not last:
        concatenate sql,","
    end if
end for

concatenate sql," FROM test"

漏洞取决于列名的来源。如果你有列名的内部不可变列表,那么没有风险,但如果它们以某种方式来自外部源,例如使用该应用程序的用户,那么它肯定容易进行SQL注入。 / p>