将SQL保存在c#源代码或Stored Procs中有哪些优点/缺点?我一直在和一个朋友讨论这个问题,我们正在做一个开源项目(c# ASP。网论坛)。目前,大多数数据库访问都是通过在c#中构建内联SQL并调用SQL Server DB来完成的。所以我在试着确定,对于这个特定的项目,哪个是最好的。
到目前为止,我有:
in Code的优点:
更容易维护-不需要运行SQL脚本来更新查询 更容易移植到另一个DB -没有pros到移植
存储Procs的优点:
性能 安全
将SQL保存在c#源代码或Stored Procs中有哪些优点/缺点?我一直在和一个朋友讨论这个问题,我们正在做一个开源项目(c# ASP。网论坛)。目前,大多数数据库访问都是通过在c#中构建内联SQL并调用SQL Server DB来完成的。所以我在试着确定,对于这个特定的项目,哪个是最好的。
到目前为止,我有:
in Code的优点:
更容易维护-不需要运行SQL脚本来更新查询 更容易移植到另一个DB -没有pros到移植
存储Procs的优点:
性能 安全
当前回答
我喜欢存储过程,不知道有多少次我能够使用存储过程对应用程序进行更改,而不会对应用程序产生任何停机时间。
作为Transact SQL的忠实粉丝,调优大型查询已被证明对我非常有用。我已经6年没有写过任何内联SQL了!
其他回答
我不是存储过程的狂热爱好者,但我在一种情况下使用它们:
当查询相当大时,最好将其作为存储过程存储在数据库中,而不是从代码中发送。这样,就不会从应用服务器向数据库发送大量字符串字符,而只发送“EXEC SPNAME”命令。
当数据库服务器和web服务器不在同一个网络上(例如,internet通信)时,这是多余的。即使事实并非如此,太大的压力也意味着大量的带宽浪费。
但是,伙计,管理起来太糟糕了。我尽量避开他们。
存储过程的优点 1).提高安全性,因为存储过程中的SQL本质上是静态的(大多数)。这将防止SQL注入。 2)。可重用性。如果需要为多个应用程序/组件返回相同的数据,这可能是一个更好的选择,而不是重复SQL语句。 3).减少客户端与数据库服务器之间的调用。
我不确定其他数据库,但您可以在大型机上的db2中使用主机语言创建存储过程,这使得它们非常强大。
@Terrapin - scprocs同样容易受到注射攻击。正如我所说:
总是参数化所有的查询-永远不要内联用户输入的东西,你会没事的。
这适用于sprocs和动态Sql。
我不确定不重新编译你的应用程序是一个优势。我的意思是,在重新上线之前,您已经针对该代码(应用程序和DB)运行了单元测试。
@Guy -是的,你是对的,sproc确实让你控制应用程序用户,这样他们就只能执行sproc,而不是底层的操作。
我的问题是:如果所有人都通过你的应用程序访问它,使用连接和用户只有有限的更新/插入权限等,这个额外的级别是否增加了安全性或额外的管理?
我的观点是后者。如果他们已经破坏了您的应用程序,可以重新编写它,那么他们还有很多其他的攻击可以使用。
如果动态内联代码,Sql注入仍然可以针对这些spprocs执行,所以黄金法则仍然适用,所有用户输入必须始终参数化。
@Keith
安全?为什么scprocs会更安全?
正如Komradekatz所建议的,您可以禁止访问表(对于连接到DB的用户名/密码组合),而只允许SP访问。这样,如果有人获得了数据库的用户名和密码,他们可以执行SP,但不能访问表或数据库的任何其他部分。
(当然,执行scproc可以给他们所有他们需要的数据,但这将取决于可用的scproc。给他们访问表的权限,他们就能访问所有东西。)
我在其他答案中没有发现的一点是:
如果在您的环境中,数据库及其模式是体系结构的核心,应用程序的作用更小,那么更多地使用存储过程可能是有意义的,这可能有助于为所有需要访问DB的应用程序提供一个级别基础,从而减少代码重复(例如,您确定所有访问DB的应用程序都是用c#或其他。net语言编写的吗?)
另一方面,如果应用程序具有更核心的角色,而DB更多地充当应用程序的备份存储,那么减少存储过程的使用并通过提供一个公共持久性层(可能基于ORM工具/框架)来减少代码重复可能是明智的。
在这两种情况下,重要的是不要将DB视为存储过程的方便存储库。将它们保存在版本控制系统的源文件中,并尽可能地尝试自动化它们的部署(这实际上对所有与模式相关的构件都有效)。