6

我通常在 .NET 中编写我的 SQL

sql.Append("SELECT id, code, email FROM mytable WHERE variable = @variable ");

然后做这样的事情:

using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["defaultConnection"]].ConnectionString))
{
    using (SqlCommand myCommand = new SqlCommand(sql.ToString(), conn))
    {
        myCommand.Parameters.AddWithValue("@variable", myVariableName");
        ...

但是当我得到的数据直接来自数据库时,我也应该这样做 addParameter 吗?

likesql.Append(string.Format("SELECT group_id, like_text FROM likeTerms ORDER BY group_id ASC "));

DataTable dtLike = SqlHelper.GetDataTable(likesql.ToString());

foreach (DataRow dr in dtLike)
{
    buildsql.Append(".... varId = " + dr["group_id"].ToString() + "...");

    ...

这可以接受吗?什么是最佳实践?

4

4 回答 4

17

您应该始终使用参数:

  • 数据库中的值来自哪里?
  • 你能相信,在你的例子中,'group_id' 没有被修改为你不期望的东西吗?

不相信任何人

具有有限数据库访问权限的人可以直接注入其他地方使用的字段吗?

表现

此外,它有助于性能。缓存的执行计划将忽略参数的值,这意味着您可以避免服务器在每次参数更改时重新编译查询。

于 2012-11-20T23:46:07.193 回答
5

当您使用带参数的 DbCommands 时,参数永远不会“内联”到查询中。相反,查询和参数数据被传递到一个特殊的系统存储过程 sp_executesql。以这种方式完成时,您拥有的任何参数数据都将被视为完全一样,并且不会从查询字符串中解析出来;因此,可能已经通过验证的注入命令永远不会执行。

使用参数是基于 ADO.NET 的数据访问层的最佳实践,无论数据来自何处,并且是 IMO 应该在此级别完成的唯一方法(如果您不使用 ORM)。你永远不应该将从 web 或 windows 窗体中检索到的值连接到 SQL 语句中,如果你遵循该规则,为什么你会因为你有信心甚至确定信息不是直接的而以不同的方式实现它来自用户?遵循相同的模式,如果并且当您公开该方法以保留用户指定的数据时,您将不会被烧毁。

于 2012-11-20T23:45:20.483 回答
4

这是可以接受的(从某种意义上说,如果您知道有时可能会正常工作的限制)。

使用数据库中的值并使用字符串连接构建 SQL 查询是一种好习惯 - 否。

即在您的示例中,如果“group_id”是"'--"什么?

于 2012-11-20T23:44:55.910 回答
0

我建议使用存储过程,但这是可以接受的 我还建议您在将参数分配给查询之前对其进行清理

于 2012-11-20T23:51:34.533 回答