在ASP.NET应用程序中完全避免ad hoc sql是一个好习惯吗?

时间:2011-05-13 13:11:33

标签: asp.net sql sql-server database-design stored-procedures

而是仅创建存储过程并从代码中调用它们?

7 个答案:

答案 0 :(得分:4)

完全取决于你正在做的事情。

作为一般规则,存储过程将使其查询计划的缓存优于动态生成的SQL语句。维护索引也会稍微容易一些。

但是,动态生成的SQL语句可以缓存其查询计划,因此差异很小。

动态生成的SQL语句也会带来安全风险 - 始终对它们进行参数化。

那说sprocs很难维护和更新,他们将DB逻辑和.Net代码分开,这样开发人员就很难将数据访问方法的内容拼凑在一起。

此外,要修改或更新SQL字符串,只需更改代码即可。要修复或更新sproc,你必须更改数据库 - 通常是一个更麻烦的选项。

因此我不建议将其作为“一刀切”的最佳做法。

答案 1 :(得分:4)

动态SQL和/或ad hoc SQL有一个地方,但需要根据特定的使用需求进行调整。

存储过程是迄今为止几乎所有情况下的最佳实践,应首先予以强烈考虑。

这个问题比procs或ad hoc稍大,因为数据库有各种各样的工具来定义它的接口,包括表,视图,函数和过程。

这里的人已经提到了执行计划和参数化,但到目前为止,我认为最重要的是任何依赖于暴露的基表到用户的技术意味着你失去了数据库改变其底层实现的能力或垂直或水平控制安全性。至少,我只会将视图暴露给典型的应用程序/用户/角色。

在应用程序或用户帐户只能访问EXEC SP的情况下,该帐户甚至不可能希望使用表单的SQL注入:“; SELECT name,password from用户;”或者“;从用户那里删除”;或者“; DROP TABLE USERS;”因为该帐户除了EXEC之外没有任何东西(当然也没有DDL)。例如,您可以在SP级别控制列可见性,而不必拒绝在员工工资列上选择。

换句话说,除非您愿意将db_datareader授予public(因为这实际上是您在LINQ-to-tables时所做的事情),那么您在应用程序中需要某种真实的安全性,而SP是唯一的方法LINQ-to-views可能是可以接受的。

答案 2 :(得分:2)

这里没有正确或错误的答案。两者都有好处,可以通过谷歌搜索轻松获得。不同要求的不同项目可能会引导您找到不同的解决方案它不像你想要的那样是黑色或白色。你也可以把ORM扔进去。如果您更喜欢数据层中的sql查询而不是存储过程,请确保使用参数化查询。

答案 3 :(得分:1)

sp中的sql易于维护,sql在应用程序中保持不变。

跳转到sql实例,修改sp,测试它,然后部署sp,而不是修改应用程序中的代码,测试它,然后部署应用程序,这样更快更容易。

答案 4 :(得分:0)

这取决于表格中的数据分布。缓存准备好的查询计划和存储过程,计划本身取决于表统计信息。

假设您正在构建一个博客,并且您的posts表具有user_id。而且你经常做的事情如下:

select posts.* from posts where user_id = ? order by published desc limit 20;

假设帖子(user_id)和帖子(发布的desc)的索引。

另外假设你有两位作者,很久以前写过3篇文章的作者1,以及自那以后写过10k帖子的作者2。

在这种情况下,即席查询的查询计划将会有很大差异,具体取决于您是获取author1帖子还是author2帖子:

  • 对于author1,数据库将决定在user_id上使用索引并对结果进行排序。
  • 对于author2,数据库将使用已发布的索引读取前20行。

如果您准备声明,规划人员将选择其中之一。假设第二个(我认为很可能):应用于author1,这意味着通过索引遍历整个表 - 这比最优计划要慢得多。

答案 5 :(得分:0)

如果简单是你的目标,那么ORM对于简单的数据库操作来说是一个很好的做法

像Entity Framework,nHibernate,LINQ to SQL等ORM将管理数据访问和存储库层的代码创建,并为您提供表示表的强类型对象。这可以带来更清洁,更易维护的架构。

保存更复杂查询的存储过程。您可以在此处利用高级SQL和缓存查询计划。

答案 6 :(得分:-2)

  1. 动态SQL - 错误
  2. 存储过程 - 更好
  3. Linq-To-SQL或Linq-to-EF(或ORM工具) - 最佳
  4. 由于您没有编译时检查,因此您不希望在应用程序中使用动态SQL。存储过程至少会被检查,但它仍然不是一个有凝聚力的usnit的一部分,并且将业务逻辑移除到数据库层。 Linq-To-EF将允许业务逻辑保留在您的应用程序中,并允许您对语法进行编译时检查。