【发布时间】:2020-02-20 23:01:45
【问题描述】:
我有以下代码,看起来很标准,但是在查询中是另一个 SQL 语句,因此“AS QUERY”位于 SQL 字符串的末尾。我想知道是否有一种复杂的方法来参数化以下 SQL 命令,而不是将整个查询连接在一起。
我能想到的唯一解决方案是将查询作为字符串而不是将其作为SQLCommand 类型对象并启动2个命令。 1个可以,另一个显示数据的预览。
public static CommandStatus<int> GetQueryRecordCount(SqlConnection connection, String query)
{
String sql = "SELECT COUNT(1) FROM (" + query + ") AS QUERY";
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = sql;
cmd.Connection = connection;
cmd.CommandTimeout = GetTimeout();
try
{
SqlDataReader dataReader = cmd.ExecuteReader();
dataReader.Read();
String count = dataReader[0].ToString();
dataReader.Close();
return new CommandStatus<int>(Int32.Parse(count));
}
catch (Exception e)
{
return new CommandStatus<int>("Failed to GetQueryRecordCount[" + sql + "]:" + e.Message, e);
}
}
String SQL 最终会变成这样
"SELECT COUNT(1) FROM (SELECT TOP 20 [RecordID],[Name],[SonsName],[DadsName],[MothersName],[DaughtersName] FROM [dbo].[sample] ) AS QUERY"
【问题讨论】:
-
该字符串中没有值,因此除了
TOP返回的行数之外没有其他参数。AS QUERY不是关键字,它只是子查询的别名。无论如何,这段代码有什么意义?如果少于 20 个,它将返回 20 个或样本数。 -
“查询”参数从何而来?如果它是同一模块中的可用值之一,则 sql 注入的风险非常小。另一方面,如果它来自某些用户输入,则存在真正的 sql 注入风险。
-
你也许可以使用 SqlParameter。这通常用于以“安全”的方式传递参数
-
@DanielSchmid 表名和列名不能作为 SQL 参数提供。
-
@Amy:好吧,他们可以,只要您随后动态构建生成的查询。 (我提到这并不是迂腐,而是因为将它们作为参数传递给存储过程,然后检查白名单是一种合法的业务方式,而不是必须动态构建整个事物并打开完全任意查询的大门.)
标签: c# sql-injection