是否将业务逻辑放入存储过程中?


21

关于“-是否将业务逻辑放入存储过程?”这一主题一直存在争议。如果我们决定不使用ORM工具并且不将业务逻辑放入存储过程中,那么我们将业务逻辑放在哪里?

在以前的应用程序中,我始终倾向于仅将所有业务逻辑放入存储过程中。然后从.NET代码中,我使用数据访问应用程序块调用这些存储过程。SQLHelper等。但这并非一直都是这种情况。所以我做了一些谷歌搜索,但最终陷入了混乱。

有什么建议...吗?


我有偏见->总是存储过程。但后来我有偏见。忘记敏捷编程,可悲的现实是,在商业世界中,更改总是临时发生的,需要“立即”完成。存储过程可以做到这一点。它是一个救生员。试图通过代码库进行此类更改将不可行。
2011年

4
@Darknight,在很大程度上取决于您的平台和体系结构来做出这样的声明。我不明白为什么将存储过程部署到数据库比执行构建和部署脚本来构建新的WAR文件,部署它并重新启动应用程序服务器要少得多的时间。
maple_shaft

7
存储过程-计算机科学化粪池。
孟格斯·庞

1
存储过程-就像其他工具一样。
sam yi

Answers:


15

我将采用务实的方法-从历史上看,将业务逻辑保留在存储的proc中的主要“好处”是出于性能方面的考虑(2.5层体系结构),而将业务逻辑分为BLL层(3 / N层)通常比使用BLL层更清洁。维护角度,并且更易于测试(模拟/存根出数据访问权限)。

但是,考虑到像LINQ2SQL,EF和NHibernate这样的启用LINQ的.NET ORMS现在可以创建参数化的SQL查询,可以在其中缓存查询计划,可以将其转义用于SQL注入等,因此我认为向3 / N层体系结构迈进是比以往任何时候都更具吸引力,并且可以完全避免大多数SPROC(尤其是以查询为中心的SPROC)。.NET中的存储库模式通常公开IQueryable / accept Expression树形参数,从而允许对表进行类型安全且灵活的访问。(个人而言,在SOA类型的体系结构中,我不会在BLL之外公开IQueryable,即,您的Service和Presentation层应该使用一组定义良好的方法。原因是否则您将无法完全测试系统,而您将无法

但是,在一个体面的系统中,总会有一些例外,出于性能原因,可能仍然需要将一块真正的数据密集型代码编写为存储过程。在这些情况下,我将保留SPROC,并通过ORM公开SPROC,但仍将函数作为BLL上的传递方法公开。


1
+1使得在应用程序层更容易编写单元测试,但是自动化的DB单元测试框架已经走了很长一段路。
maple_shaft

14

作为一名Java开发人员,我的首选是将业务逻辑放入BLL中(很好且易于实现的源代码控制,熟悉程度等)。

但是,在为拥有许多使用不同技术(C#,Java,Pick(不要问)的分布式应用程序)的大型企业工作之后,使用存储过程的一个明显好处就变得显而易见:

可以在不同的应用程序之间共享存储过程


非常好的点
NoChance

1
这是真的,我们使用它在我们的环境中产生了良好的影响。但是,使用数据层共享代码始终对我来说有点危险。如果您有一个给定的逻辑/数据的多个使用者,那么我宁愿在它前面放置一个服务,而不是让一个数据库拥有多个使用者。
RationalGeek

2
如果将数据管理分成多个库,则这些库在理论上也可以在不同的应用程序之间共享...
glenatron 2011年

2
我部分同意。所有这些技术都直接访问数据库。因此,您正在使用存储过程在其中共享通用代码。您也可以通过使用中间层来解决相同的问题,并让异构解决方案访问中间层而不是数据库,并且中间层共享此类代码。
Ekevoo 2014年

1
对于这个答案,是6年后的baloney-只有数据进入数据库。您将逻辑放在其中,会遇到很多麻烦。只需使用您选择的访问数据库的语言来构建微服务。
NimChimpsky '16

6

我们的团队在这里有一个软性规则。有时最好在T-SQL中解决业务逻辑,有时在c#(业务层)中更容易做到。

因此,我们有一个务实的解决方案:将其放在更合适的位置。我知道理论有时对此非常严格...但这就是理论:-)


2
当然这是最糟糕的解决方案吗?维护人员如何知道逻辑的存储位置?我想,有时它还会潜入应用程序层,甚至更糟的是UI?
Paul T Davies,

2
不。它总是进入业务层或T-SQL。在维护方面,弄清楚逻辑的存储位置可能是最小的问题。
gsharp 2011年

当有人加入团队并且您告诉他们这个规则时会发生什么?他们应该如何知道什么地方“更合适”?在我看来,这几乎是非规则。基于个人非常主观。
RationalGeek

3
伙计们,是吗?我们雇用具有思维能力的人,并具有一定的经验。然后..哦,是的,他们有话要问并进行交谈。我可以说我们的软件只需要很少的维护,并且我们团队中的几乎每个人都可以很好地实现新功能。我们所做的不能错。
gsharp 2011年

4
我真的没有感觉到将C#误用于SQLServer可以做得更好的事情,反之亦然。
gsharp 2011年

3

两者都有优点和缺点(我认为):

如果您不使用某种SQL源代码控制(很多地方都没有),并且有多个开发人员在使用它们,则存储过程可能会成为噩梦。有人可以更改存储过程,而忘了更新调用该过程的代码,而在您不知道它之前,您刚刚构建并部署了一个站点,该站点将引发未处理的异常(参数计数不匹配等)。

另一方面,存储过程可以在某些情况下更快地修复错误。如果存储过程中存在错误,则只需对其进行修复即可。ORM中的错误修复需要重新构建。根据您的构建过程,这可能会很长/很烦人。


如果要大量使用存储过程,则需要对源代码进行+1控制。与我合作过的许多DBA都非常反对这个想法。
RationalGeek

2

我们始终将业务逻辑放在业务逻辑层中。如果将其放在存储过程中,则在更改RDBMS后,它将丢失。


16
最后更改的是RDBMS ;-)
gsharp 2011年

这是否意味着将存储过程限制为获取,更新和插入数据...?
Pravin Patil

1
我见过的每个大型系统,实际情况是数据库就是系统。编程语言在这一点刚才的“前端”几乎变得无关紧要..
Darknight

2
@gsharp,并非总是如此。您可能想要添加另一个RDBMS(例如Oracle),或者完全替换现有的RDBMS。或者,在某些情况下,您想用伪数据替换实际数据。
šljaker

2
@šljaker当然并非总是如此。但是更可能是程序发生了变化(软件的重新设计,新的编程语言等),而不是数据库。
gsharp 2011年

2

“业务逻辑”是一个模糊的术语。我的意思是它没有一个单一的定义。经验法则是在可能的情况下尽量减少层之间的通信。因此,您无需在插入行之前向服务器发送空白的客户名称来进行检查。

在某些情况下,规则基于数据库读取。假设您要将资金从帐户1转移到帐户2。您需要读取两个帐户,确保它们状态良好,并且帐户1中的金额足够。在这种情况下,服务器是此规则的更好候选者,因为客户端(此处为BL)无需为此过程向数据库层发出3次调用。

当然,如果您需要解决方案独立于数据库,则仅针对CRUD(如果已使用)创建存储的proc。


1

逻辑应该始终在BLL中,因为:

  • 可以正确测试
  • 当SQL 20XX过时并且您需要更改为最新版本时,不必重写代码。
  • 人们不愿意立即进行更改(这似乎是SP的论点)
  • 根据我的经验,SP是开发人员错误的最大单一点,尤其是经过几代的维护/更改之后。

我认为应该有一条法律规定,SP超过X行之后,它将无法按预期运行。


动态更改有什么问题?如果存储过程中有错误并且很容易修复,请对其进行修复。这是积极的,因为这意味着您不必为琐碎的事重新发布。只要人们不开始通过更改存储过程来掩盖代码中的错误,那么我就没有问题。
AndrewC 2011年

即时更改是指未经测试且未遵循正式发布程序的内容。是的,我见过相当多的sp更改掩码代码错误。
Paul T Davies,

0

我们创建一个服务层,其中包含以所选语言实现的所有业务逻辑,并且仅将数据库用于查询。这种方法由我们强制执行,因为我们的目标是创建COTS解决方案以交付具有各种数据库实现的应用程序。在这种情况下,Hibernate被证明是我们的救星。

我认为,这种方法的最大优点是,除了数据库可移植性外,您还可以一次搜索找到所有答案。

另外,尽管有一些论坛上的答案,但我有一个朋友在一家财富100强保险公司工作,该公司在三年内完成了两次数据库转换,因为该公司选择的数据库发生了变化。


0

以我有限的经验,我更喜欢通过存储过程和其他数据库功能来保持数据完整性。例如,如果我要在两个帐户之间进行资金转移,我将编写一个存储过程。我发现能够使用多种应用程序语言很有价值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.