SP以不同方式公开暴露于外部世界
– 有些用户可以直接访问SP,
– 有些是通过WebService公开的
– 而其他人通过DCOM层封装为接口.
用户群很大,我们不确切知道哪个用户集使用哪种方法来访问数据库.
我们经常(每隔约1个月)来自用户集的请求,通过向输出添加一列或向现有输出添加一组列来修改现有SP,所有其他保持相同.
我们最初通过修改现有SP并将新请求的列添加到输出的末尾来开始这样做.但这打破了其他一些用户群构建的自定义工具,因为他们的工具具有硬编码的列数,因此添加列意味着他们也必须修改他们的工具.
此外,对于某些列,需要复杂的逻辑才能将该列放入报表中,这意味着SP性能下降,影响所有用户 – 甚至是那些不需要新列的用户.
我们正在考虑各种解决方法:
1默认参数用于控制流量
通过添加标志作为默认参数来更新现有SP并控制新功能,以控制代码路径.通过使用默认参数,如果Parameter的值设置为true,则仅调用新功能.默认情况下,它设置为False.
Advantage
>不需要新对象.
>正在进行的维护不受影响.
>测试开销仍然受到控制.
Disadvantage
>由于现有SP已修改,因此需要测试现有功能以及新功能.
>由于我们没有了解客户端工具如何调用SP,因此我们永远无法确定我们没有破坏任何东西.
>如果同一报告再次被更多请求修改将很难处理 – 意味着更多的标志和代码将变得不可读.
2新的存储过程
将为任何更改SP的签名(输入/输出)的要求创建新的存储过程.新的SP将为现有的东西调用原始存储过程,并在其上添加新需求的逻辑.
Advantage
>这里的好处是不会对现有程序产生影响,因此旧逻辑不需要测试.
Disadvantage
>只要请求更改,就需要在数据库中创建新对象.这将是数据库维护的开销.
执行计划会根据添加新参数而改变吗?如果是,那么这可能会对未请求新列的用户产生负面影响.
考虑到SP是数据库的公共接口,如果选择2,接口应该是不可变的?
什么是最佳做法,还是取决于具体情况,选择期权时应该是主要的驱动因素?
提前致谢!
解决方法
It will be difficult to handle if same report gets modified again with more requests – will mean more flags and code will become un-readable.
我个人认为这是不修改现有存储过程以容纳新列的最大原因.
当bug出现具有多个分支的存储过程时,调试变得非常困难.另外,正如您所暗示的那样,执行计划可以使用分支/ if语句进行更改. (sql using different execution plans when running a query and when running that query inside a stored procedure?)
这与面向对象的编码非常相似,你的直觉是正确的,最好是扩展现有对象而不是修改它们.
我会选择方法#2.您将拥有更多对象,但至少在出现问题时,您将能够知道受影响的存储过程具有有限的范围/影响.
随着时间的推移,我学会了水平地而不是垂直地增长对象/数据结构.换句话说,只要做出新的东西,不要让现有的东西变得越来越大.