Sql server 更好的做法是:向现有SP添加可选参数,还是添加新SP?

Sql server 更好的做法是:向现有SP添加可选参数,还是添加新SP?,sql-server,database,database-design,stored-procedures,Sql Server,Database,Database Design,Stored Procedures,我有一个生产SQL Server DB(reporting),它有许多存储过程。 SP以不同的方式公开暴露于外部世界 -某些用户可以直接访问SP, -有些是通过Web服务公开的 -而另一些则通过DCOM层封装为接口 用户群很大,我们不知道哪个用户集使用哪种方法访问数据库。 我们经常(大约每隔一个月)收到来自用户集的请求,请求通过向输出中添加一列或向现有输出中添加一组列来修改现有SP,所有其他内容保持不变。 我们最初是通过修改现有SP并将新请求的列添加到输出的末尾来实现的。但这打破了其他一些用户基

我有一个生产SQL Server DB(reporting),它有许多存储过程。 SP以不同的方式公开暴露于外部世界
-某些用户可以直接访问SP,
-有些是通过Web服务公开的
-而另一些则通过DCOM层封装为接口

用户群很大,我们不知道哪个用户集使用哪种方法访问数据库。
我们经常(大约每隔一个月)收到来自用户集的请求,请求通过向输出中添加一列或向现有输出中添加一组列来修改现有SP,所有其他内容保持不变。
我们最初是通过修改现有SP并将新请求的列添加到输出的末尾来实现的。但这打破了其他一些用户基础构建的自定义工具,因为他们的工具具有硬编码的列数,因此添加列意味着他们也必须修改他们的工具。

此外,对于某些列,需要复杂的逻辑才能将该列放入报告中,这意味着SP性能降低,影响到所有用户,即使是不需要新列的用户。

我们正在考虑各种方法来解决此问题:

1控制流量的默认参数 通过添加标志作为默认参数来控制代码路径,更新现有SP并控制新功能。通过使用默认参数,如果参数的值设置为true,则仅调用新功能。默认情况下,它设置为False。

优势

  • 不需要新对象
  • 持续维护不受影响
  • 测试开销仍在控制之中
劣势

  • 由于现有SP已被修改,因此需要测试现有功能以及新功能。
  • 由于我们对客户端工具如何调用SPs一无所知,因此我们无法确定我们没有破坏任何东西
  • 如果同一个报告再次被修改,并且请求更多,这将很难处理,这将意味着更多的标志和代码将变得不可读
2新的存储过程 将为更改SP签名(输入/输出)的任何需求创建一个新的存储过程。
新SP将为现有内容调用原始存储过程,并在其上添加新需求的逻辑

优势

  • 这样做的好处是不会对现有程序产生影响,因此不需要对旧逻辑进行测试。
劣势

  • 需要在请求更改时在数据库中创建新对象。这将增加数据库维护的开销。

执行计划是否会因添加新参数而更改?如果是,则这可能会对未请求新列的用户产生不利影响。
考虑到SP是DB的公共接口,并且接口应该是不可变的,我们应该选择选项2吗?
最佳做法是什么,或者取决于具体情况,以及选择选项时的主要驱动因素是什么?


提前谢谢

从劣势中引用第一个选项:

如果同一个报告再次被修改,并且请求更多,这将很难处理,这将意味着更多的标志和代码将变得不可读

我个人认为这是不修改现有存储过程以适应新列的最大原因

当错误出现在具有多个分支的存储过程中时,调试会变得非常困难。正如您所暗示的,执行计划可以通过分支/if语句进行更改。()

这与面向对象编码非常相似,您的直觉是正确的,即最好扩展现有对象,而不是修改它们

我会选择方法2。您将拥有更多对象,但至少在出现问题时,您将能够知道受影响的存储过程的作用域/影响有限

随着时间的推移,我学会了水平增长对象/数据结构,而不是垂直增长。换言之,只要创造新的东西,不要让现有的东西变得越来越大。

我也会投票支持#2。我见过一些将#1发挥到极致的存储过程:SPs有一个参数
@选项
和一些参数
@param1
@param2
。。。。最终的效果是,这是一个试图扮演多个存储过程角色的单个存储过程

#2的主要缺点是存储过程较多。要找到你要找的人可能会更难,但我认为这对于你获得的其他优势来说是一个很小的代价


我还想确保,您不只是复制和粘贴原始存储过程并添加一些列。我也看过太多这样的电影了。如果只添加几列,则可以调用原始存储过程并加入新列。如果这些列以前是可用的,那么这肯定会导致性能损失,但您不必更改原始存储过程(重构以获得良好的性能且不复制代码),也不必维护代码的两个副本(复制和粘贴以获得性能).

我将根据您给出的选项,建议其他几个选项

备选方案#1:添加另一个变量,但不是将其作为默认变量,而是将该变量基于客户名称。这样,客户A可以得到专门的报告,客户B可以得到稍微不同的定制报告。这增加了大量工作,因为“主要”部分的更新必须复制到所有专业客户部分。 您可以通过分支“if”语句来实现这一点

备选方案#2:添加新的