将SQL保存在c#源代码或Stored Procs中有哪些优点/缺点?我一直在和一个朋友讨论这个问题,我们正在做一个开源项目(c# ASP。网论坛)。目前,大多数数据库访问都是通过在c#中构建内联SQL并调用SQL Server DB来完成的。所以我在试着确定,对于这个特定的项目,哪个是最好的。

到目前为止,我有:

in Code的优点:

更容易维护-不需要运行SQL脚本来更新查询 更容易移植到另一个DB -没有pros到移植

存储Procs的优点:

性能 安全


当前回答

对于Microsoft SQL Server,您应该尽可能使用存储过程来帮助执行计划缓存和重用。为什么要优化计划重用?因为生成执行计划的成本相当高。

Although the caching and reuse of execution plans for ad-hoc queries has improved significantly in later editions of SQL server (especially 2005 and 2008) there are still far fewer issues with plan reuse when dealing with stored procedures than there are for ad-hoc queries. For example, SQL server will only re-use an execution plan if the plan text matches exactly - right down to comments and white space, for example, if each of the following lines of SQL were to be executed independently, none of them would use the same execution plan:

SELECT MyColumn FROM MyTable WHERE id = @id
select MyColumn from MyTable WHERE id = @id
SELECT MyColumn  FROM MyTable WHERE id = @id
SELECT MyColumn FROM MyTable WHERE id = @id -- "some comment"
SELECT MyColumn FROM MyTable WHERE id = @id -- "some other comment"

除此之外,如果你不显式地指定类型的参数然后有一个好的机会,SQL Server可能出错,例如如果您执行上面的查询与输入4,然后用@ id查询SQL Server将parametrise SMALLINT(或可能是一个非常小的整数),所以如果你然后执行相同的查询@ id的说4000,SQL Server将parametrise INT,而不会重用相同的缓存。

我认为还有其他一些问题,老实说,大多数问题都可以解决——特别是在SQL Server的后续版本中,但是存储过程通常会提供更多的控制。

其他回答

我非常支持代码而不是SPROC。第一个原因是保持代码紧密耦合,第二个原因是源代码控制的便利性,而不需要大量自定义实用程序。

在我们的DAL中,如果我们有非常复杂的SQL语句,我们通常将它们作为资源文件,并在需要时更新它们(这也可以是一个单独的程序集,并在每个db中交换,等等……)

这使得我们的代码和sql调用存储在同一个版本控制中,而不会“忘记”运行一些外部应用程序进行更新。

我站在代码这一边。我们构建了所有应用程序(包括web和客户端)使用的数据访问层,所以从这个角度来看这是DRY。它简化了数据库部署,因为我们只需要确保表模式是正确的。它简化了代码维护,因为我们不需要查看源代码和数据库。

在与数据模型的紧密耦合方面,我没有遇到太多问题,因为我看不出哪里有可能真正打破这种耦合。应用程序及其数据在本质上是耦合的。

我更喜欢使用O/R映射器,如LLBLGen Pro。

它为您提供了相对轻松的数据库可移植性,允许您使用强类型对象用与应用程序相同的语言编写数据库访问代码,并且在我看来,允许您更灵活地处理所拉回的数据。

实际上,能够使用强类型对象是使用O/R Mapper的充分理由。

这样想

你有4个web服务器和一堆使用相同SQL代码的windows应用程序 现在您意识到SQl代码有一个小问题 所以你宁愿...... 在一个地方改变过程 或 将代码推送到所有的网络服务器上,重新安装所有Windows盒子上的所有桌面应用程序(单击一次可能会有帮助)

我更喜欢存储过程

它也更容易做一个过程的性能测试,把它放在查询分析器 设置io/time on统计信息 设置showplan_text,瞧

不需要运行分析器来查看到底调用了什么

这只是我的小意思

目前在这里的其他几个线程中正在讨论这个问题。我一直是存储过程的支持者,尽管有一些很好的论据支持Linq to Sql。

在代码中嵌入查询将您与数据模型紧密地结合在一起。存储过程是一种很好的契约式编程形式,这意味着DBA可以自由地更改过程中的数据模型和代码,只要存储过程的输入和输出所表示的契约得到维护。

当查询隐藏在代码中,而不是在一个易于管理的中心位置时,调优生产数据库可能会非常困难。

这里是另一个当前的讨论