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

到目前为止,我有:

in Code的优点:

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

存储Procs的优点:

性能 安全


当前回答

在我看来,你不能在这个问题上投赞成票或反对票。这完全取决于应用程序的设计。

我完全反对在三层环境中使用sp,在这种环境中,前端是应用服务器。在这种环境中,应用服务器用于运行业务逻辑。如果你额外使用sp,你就开始在整个系统中分配业务逻辑的实现,谁负责什么就会变得非常不清楚。最终你将得到一个基本上只会做以下事情的应用服务器:

(Pseudocode)

Function createOrder(Order yourOrder) 
Begin
  Call SP_createOrder(yourOrder)
End

因此,最终你的中间层运行在这个非常酷的4个服务器集群上,每个服务器都配备了16个cpu,实际上它什么都不会做!太浪费了!

如果你有一个臃肿的gui客户端,直接连接到你的数据库或甚至更多的应用程序,这是一个不同的故事。在这种情况下,SPs可以充当某种伪中间层,将应用程序与数据模型解耦,并提供可控的访问。

其他回答

Something that I haven't seen mentioned thus far: the people who know the database best aren't always the people that write the application code. Stored procedures give the database folks a way to interface with programmers that don't really want to learn that much about SQL. Large--and especially legacy--databases aren't the easiest things to completely understand, so programmers might just prefer a simple interface that gives them what they need: let the DBAs figure out how to join the 17 tables to make that happen.

话虽如此,用于编写存储过程的语言(PL/SQL就是一个臭名昭著的例子)是相当残酷的。它们通常不提供您在当今流行的命令式语言、OOP或函数式语言中看到的任何细节。认为COBOL。

因此,请坚持使用仅抽象了关系细节的存储过程,而不是那些包含业务逻辑的存储过程。

@Terrapin - scprocs同样容易受到注射攻击。正如我所说:

总是参数化所有的查询-永远不要内联用户输入的东西,你会没事的。

这适用于sprocs和动态Sql。

我不确定不重新编译你的应用程序是一个优势。我的意思是,在重新上线之前,您已经针对该代码(应用程序和DB)运行了单元测试。


@Guy -是的,你是对的,sproc确实让你控制应用程序用户,这样他们就只能执行sproc,而不是底层的操作。

我的问题是:如果所有人都通过你的应用程序访问它,使用连接和用户只有有限的更新/插入权限等,这个额外的级别是否增加了安全性或额外的管理?

我的观点是后者。如果他们已经破坏了您的应用程序,可以重新编写它,那么他们还有很多其他的攻击可以使用。

如果动态内联代码,Sql注入仍然可以针对这些spprocs执行,所以黄金法则仍然适用,所有用户输入必须始终参数化。

在某些情况下,在代码中动态创建的sql可能比存储的proc具有更好的性能。如果您已经创建了一个存储的proc(例如sp_customersearch),它必须非常灵活,因此具有许多参数,非常复杂,那么您可能可以在运行时在代码中生成一个更简单的sql语句。

有人可能会说,这只是将一些处理从SQL转移到web服务器,但总的来说,这是一件好事。

这种技术的另一个优点是,如果你在SQL分析器中查找,你可以看到你生成的查询,调试它比看到一个存储的带有20个参数的proc调用要容易得多。

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

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

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

@Keith

安全?为什么scprocs会更安全?

存储过程提供了抵御SQL注入攻击的内在保护。

然而,您并没有完全受到保护,因为您仍然可以编写容易受到此类攻击的存储过程(即存储过程中的动态SQL)。