假设我有一个从SELECT查询返回数据的存储过程。我想根据我传递的参数对这些结果略有不同。我想知道是否有更好的设计让多个存储过程采用一个或没有参数来执行此操作(例如,GetXByDate或GetXByUser),或者一个存储过程具有多个参数来执行该批次(例如,GetX)?
第一个选项的优点是它更简单,也许更快,但缺点是查询的本质是在存储过程中重复,需要在几个地方维护。
第二个选项的优点是查询只出现一次,但缺点是查询更复杂,更难以排除故障。
您在解决方案中使用了什么?为什么?
答案 0 :(得分:4)
更复杂的存储过程对于SQL Server的编译来说更复杂 正确并快速有效地执行。
即使在大型存储过程中,您也必须拥有多个查询副本,或者在其中添加大量CASE和IF,从而降低性能。所以你并没有因为把所有东西放在一起而获得太多收益。
根据我的个人经验,我还考虑使用大型SQL sp代码,其中包含许多分支,这些分支更难以维护,而且还有一些较小且简单的sprocs。
您可以考虑使用视图和UDF来减少查询代码的复制粘贴。
如果您不关心性能(Intranet应用程序,查询不那么重,请不要经常运行),您可能会发现使用通用的sproc非常方便。
答案 1 :(得分:4)
我会像处理类中的方法一样处理存储过程。它应该做一件事而且干脆做。考虑将相同类型的重构/代码气味规则应用于您的应用程序代码存储过程。
答案 2 :(得分:2)
我更喜欢GetXByDate,GetXByUser,...对于简单的存储过程,基于它们无论如何都需要很少的维护,在这种情况下我认为维护重复的代码比复杂的代码更容易。
当然,如果你有更复杂的存储过程,这可能不是真的。 GetAndProcessXByDate可以更好地简化为GetXByDate,GetXByUser,...调用另一个存储过程ProcessX。
所以我猜最终的答案是:它取决于......:)
答案 3 :(得分:2)
我是第二个@tvanfosson。
但是,我想补充一点,你可以做到这两点:有一个多用途的sproc(例如GetX),它包含整个查询类的基本逻辑,并将它包装在一系列较小的sprocs中(GetXY,GetXZ )执行大的,传递适当的参数。
这意味着你不要重复自己,但你也可以为客户端应用程序提供一个简单的界面:一个只调用GetXY的应用程序不必了解GetXZ。
我们有时会使用这种方法。
答案 4 :(得分:1)
单个存储过程的一个优点是,如果您使用生成的C#数据访问层(如LinqToSQL),则会生成单个类来表示结果集。
答案 5 :(得分:1)
AJs方法为您提供两全其美的体验。不得不夸大在几个sprocs中维护重复代码的痛苦。
构建Sproc和UDF模块以供常用,并从特定于任务的sprocs中调用它们。
答案 6 :(得分:0)
谁/什么会调用这些存储过程?我不会正常编写SELECT语句的存储过程,正是因为你可能需要许多不同的SELECT语句,包括与其他表的连接等。