我有一个过滤器对象来查询包含许多列的表,而不是写一个覆盖所有列的条件(允许可选的过滤),如下所示:
WHERE ((:value0 IS NULL) OR (column_name0 = :value0)) AND ((:value1 IS NULL) OR (column_name1 = :value1)) AND... etc
每列都。相反,我理想情况下我希望能够将字段名称作为参数传递:
WHERE :column_name0 = :value0 AND column_name1 = :value1 AND... etc
这是不可能的,因为在解析时需要列(类似于此答案given here)。
你如何克服这个问题? - 我真的不想在添加或删除新列时维护SQL(正如你在第一个例子中所做的那样)并且我认为将列名称直接构造到命令字符串中会很危险,因为这可能允许sql注入。
请注意,此代码位于Web服务之后。
答案 0 :(得分:23)
确保最终用户无法直接提供列名,并且在手动构建查询时应该是安全的。如果需要在运行时找出哪些列名有效,可以使用以下查询:
SELECT column_name
FROM information_schema.columns
WHERE table_schema='public' AND table_name='yourtablename'
答案 1 :(得分:1)
我认为最简单的解决方案是动态构建SQL语句。
如果您使用用户提供的数据参数,则无法进行SQL注入。
答案 2 :(得分:0)
示例:
NpgsqlCommand command = new NpgsqlCommand(SQL, Connection);
Npgsql.NpgsqlDataReader Resource = command.ExecuteReader();
while (this.Resource.Read())
{
for (int i = 0; i < this.Resource.FieldCount; i++)
{
string field = this.Resource.GetName(i).ToString();
}
}