你为什么要使用参数?

时间:2013-04-11 01:51:58

标签: parameters ado.net

我看到很多关于如何在ADO.net中使用参数以及让我开始使用c#http://csharp-station.com/Tutorial/AdoDotNet/Lesson06的优秀网站,说..

        // don't ever do this
        // SqlCommand cmd = new SqlCommand(
        // "select * from Customers where city = '" + inputCity + "'");

但我似乎无法得到你不应该这样做的答案。毫无疑问,有一个很好的理由,但我似乎无法找到它。有人可以请我填写,所以我可以在将来向新来的人回答这个问题(我喜欢帮助工作中的人学习代码)。对于一个学习c#的新人来说,我认为大多数人会发现代码行数较少,这似乎是一场胜利。仅仅是因为将字符串加在一起比使用参数更费力吗?

1 个答案:

答案 0 :(得分:1)

请仔细考虑如果有人将以下内容输入您应用中的城市文本框中会发生什么:

  

';从客户处删除; -

你最终会构造一个如下所示的sql字符串:

select * from Customers where city = '';DELETE FROM Customers;--'

恰好是两个语句和一个注释,你的sql提供者非常乐意执行两个。现在,数据库连接也可能以用户身份运行而没有从该表中删除所需的权限...但它可能具有其他权限,例如从其他表中读取数据以获取社会保险号或信用卡等信息,或者也许插入具有管理权限的新帐户记录。熟练的攻击可以使用它来做任何事情。

编写一个简单的转义或清理函数可能很诱人。不要这样做。首先,它没有完全解决问题。查询参数将用户数据与sql代码完全隔离,这样即使数据库也始终将用户输入视为变量值,并且永远不会将其直接放入查询字符串中。使用逃脱功能可以让你与破解者进行军备竞赛。

另一个原因是表现。数据库在将查询转变为执行计划以解决数据方面会遇到很多麻烦。这么多,他们经常缓存计划,以查询文本的哈希作为关键。如果不使用参数化查询,则每次都会出现缓存未命中。

最后,我只是简单地发现参数化查询更容易使用。对于复杂的查询,我可能会在查询上方添加注释,如下所示:

/*DECLARE @someVariable varchar(12);
  DECLARE @OtherVariable varchar(50);
  DECLARE @thirdVariable int;
  ...*/
var sql = 
"SELECT <columns>
 FROM table t"
 INNER JOIN othertable o ON t.ID = o.tableID"
 WHERE someColumn = @someVariable AND ...";

using (var cn = new SqlConnection(" ... "))
using (var cmd = new SqlCommand(sql, cn))
{
    cmd.Parameters.Add()
    //...

这样做是什么时候维护这个查询,我可以快速将查询及其变量声明复制/粘贴到Management Studio或其他查询工具中,当我完成后,我可以快速将整个混乱移回到客户端代码。对于一个内容来说,这并不是什么大问题,而且真正庞大/复杂的查询通常最终会成为存储过程或视图,但是这个真的非常有帮助的这个最佳位置...而且它结果更多事情最终会在你认为的最佳位置结束。