作为一名主要编写C#代码的开发人员,我在编写C#代码时采用了一些良好的实践。但是,当我有时编写存储过程时,我很难将这些实践应用于存储过程代码。
在多个场合中,我继承了可怕的存储过程代码,前三或四层存储过程设置了一些临时表,并且大部分只是互相调用。没有真正的工作,只有几行代码。然后最后调用“最终”存储过程,一个3000-5000行SQL代码的巨兽。该代码通常存在许多代码异味,例如代码重复、错综复杂的控制流(又称意大利面条式代码)以及一个方法依次堆叠做了太多事情,没有清晰的分离一块工作从哪里开始和结束(甚至没有注释作为除数)。
我还注意到使用了被注释掉的select语句,从中间临时表中进行选择。这些选择可以在调试目的下重新打开,但需要在期望特定顺序返回结果集的任何调用代码之前删除。
显然,我的团队成员也共享着我缺乏良好SQL编写实践的问题。
那么...(真正的问题来了)...编写模块化可维护存储过程的良好实践是什么?
自制的实践方法和参考书籍/博客都可以。这些方法以及帮助执行某些任务的工具都可以。
让我们总结一些我没有找到良好实践的领域
- 模块化和封装(存储过程之间的通信是否真的要通过临时表进行?)
- 在C#中,我使用程序集、类和带有访问修饰符的方法来实现这一点。
- 调试/测试(比修改调试目标更好吗?)
- 调试工具?
- 调试跟踪?
- 测试夹具?
- 强调代码/逻辑/数据/控制流使用代码的结构
- 在C#中,我重构并拆分较小的方法,每个方法只执行一个逻辑任务。
- 代码复制
我大多数接触到的是SQL Server作为数据库管理系统,但欢迎提供DBMS通用答案或指出其他DBMS特性对上述情况有帮助的答案。
为了提供一些背景:我遇到的大多数存储过程都是在报告场景中,在这种场景下,基础是从大表中创建一些汇总值。但是在此过程中,您需要排除某些异常表中出现的某些值,添加尚未完成的某些内容表中的一些值,与去年进行比较(您能想象处理产品在年度之间更改部门的丑陋代码吗?)等等。