将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的优点:
性能 安全
当前回答
我在其他答案中没有发现的一点是:
如果在您的环境中,数据库及其模式是体系结构的核心,应用程序的作用更小,那么更多地使用存储过程可能是有意义的,这可能有助于为所有需要访问DB的应用程序提供一个级别基础,从而减少代码重复(例如,您确定所有访问DB的应用程序都是用c#或其他。net语言编写的吗?)
另一方面,如果应用程序具有更核心的角色,而DB更多地充当应用程序的备份存储,那么减少存储过程的使用并通过提供一个公共持久性层(可能基于ORM工具/框架)来减少代码重复可能是明智的。
在这两种情况下,重要的是不要将DB视为存储过程的方便存储库。将它们保存在版本控制系统的源文件中,并尽可能地尝试自动化它们的部署(这实际上对所有与模式相关的构件都有效)。
其他回答
当存储过程被用于应用程序和数据库之间时,它们是最糟糕的。上面提到的使用它们的许多原因都可以由视图更好地处理。
有关安全的论点是站不住脚的。它只是将安全问题从应用程序转移到数据库。代码就是代码。我曾见过一些存储过程从应用程序中获取SQL,并使用它构建容易受到SQL注入攻击的查询。
一般来说,它们往往会在所谓的数据库开发人员和所谓的应用程序开发人员之间造成裂痕。实际上,所有编写的代码都是应用程序代码,只是执行上下文的不同。
使用丰富的SQL生成库,如LINQ, Rails ActiveRecord或Hibernate/NHibernate,使开发更快。在混合中插入存储过程会降低速度。
SQL注入攻击呈上升趋势。有人很容易找到这些代码并在你的网站上运行注入攻击。您必须始终始终将查询参数化。最好不要在动态SQL查询上运行exec(@x)。在我看来,使用内联SQL并不是一个好主意。
有些人认为,存储过程很麻烦,因为它们是另一组需要与代码分开维护的项。但是它们是可重用的,如果你在查询中发现了一个错误,你可以在不重新编译的情况下修复它们。
存储过程的优点 1).提高安全性,因为存储过程中的SQL本质上是静态的(大多数)。这将防止SQL注入。 2)。可重用性。如果需要为多个应用程序/组件返回相同的数据,这可能是一个更好的选择,而不是重复SQL语句。 3).减少客户端与数据库服务器之间的调用。
我不确定其他数据库,但您可以在大型机上的db2中使用主机语言创建存储过程,这使得它们非常强大。
@Terrapin - scprocs同样容易受到注射攻击。正如我所说:
总是参数化所有的查询-永远不要内联用户输入的东西,你会没事的。
这适用于sprocs和动态Sql。
我不确定不重新编译你的应用程序是一个优势。我的意思是,在重新上线之前,您已经针对该代码(应用程序和DB)运行了单元测试。
@Guy -是的,你是对的,sproc确实让你控制应用程序用户,这样他们就只能执行sproc,而不是底层的操作。
我的问题是:如果所有人都通过你的应用程序访问它,使用连接和用户只有有限的更新/插入权限等,这个额外的级别是否增加了安全性或额外的管理?
我的观点是后者。如果他们已经破坏了您的应用程序,可以重新编写它,那么他们还有很多其他的攻击可以使用。
如果动态内联代码,Sql注入仍然可以针对这些spprocs执行,所以黄金法则仍然适用,所有用户输入必须始终参数化。
I'm firmly on the side of stored procs assuming you don't cheat and use dynamic SQL in the stored proc. First, using stored procs allows the dba to set permissions at the stored proc level and not the table level. This is critical not only to combating SQL injection attacts but towards preventing insiders from directly accessing the database and changing things. This is a way to help prevent fraud. No database that contains personal information (SSNs, Credit card numbers, etc) or that in anyway creates financial transactions should ever be accessed except through strored procedures. If you use any other method you are leaving your database wide open for individuals in the company to create fake financial transactions or steal data that can be used for identity theft.
存储的proc也比从应用程序发送的SQL更容易维护和性能调优。它们还允许dba查看数据库结构更改对数据访问方式的影响。我从未遇到过允许动态访问数据库的优秀dba。