【发布时间】:2011-08-24 19:21:51
【问题描述】:
作为主要编写 c# 的开发人员,我在编写 c# 代码时采用了一些好的做法。当我有时编写存储过程时,我很难将这些做法应用到存储过程代码中。
在某些情况下,我继承了噩梦般的存储过程代码,前三四层存储过程设置了一些临时表并主要相互调用。没有完成真正的工作,只有几行代码。然后最后调用了“最终的”存储过程,一个 3000-5000 行 SQL 代码的大怪物。该代码通常有很多代码气味,例如代码重复、复杂的控制流(又名意大利面条)和一种方法,该方法将太多的事情堆叠在一起,没有明确区分一块工作的开始和结束位置(甚至不是一个注释为除数)。
我还注意到从中间临时表中选择的注释选择语句的使用。可以出于调试目的重新打开选择,但需要在任何期望返回结果集的特定顺序的调用代码之前删除。
显然我的队友也分享了我缺乏良好的 SQL 编写习惯。
所以...(真正的问题来了)...编写模块化可维护存储过程的良好做法是什么?
欢迎自制实践和参考书籍/博客。有助于完成某些任务的方法和工具。
让我们总结一些我没有找到好的做法的领域
- 模块化和封装(通过临时表进行存储过程通信真的可行吗?)
- 在 c# 中,我使用带有访问修饰符的程序集、类和方法来实现这一点。
- 调试/测试(比修改调试目标好?)
- 调试工具?
- 调试跟踪?
- 测试夹具?
- 使用代码强调代码/逻辑/数据/控制流代码的结构
- 在 c# 中,我重构并分解了较小的方法,每个方法只执行一项逻辑任务。
- 代码重复
大多数情况下,我将 SQL Server 作为 DBMS 遇到,但 DBMS 不可知论者的答案或指出其他 DBMS 功能的答案:在上述情况下提供帮助的答案也是受欢迎的。
提供一些背景知识:我遇到的大多数大型存储过程都在报告场景中,其中基础只是从大表中创建一些汇总值。但是一路上你需要排除一些恰好在某个异常表中的值,在一些尚未完成的东西表中添加一些值,与去年相比(你能想象处理产品更换部门的丑陋代码吗?年之间?)等
【问题讨论】:
-
由于这些原因以及无法在 SCM 中使用存储过程,除了最必要和最明显的用途(触发器等)之外,我已经避免使用它们。我们将业务逻辑保留在业务层 (.NET) 中,并为此使用数据库——一个数据库。
-
理想情况下,存储过程不应调用其他存储过程。这就是 BL 层的用途。不幸的是,如果您已经拥有一个充满嵌套 SP 调用的数据库,那么这种情绪并没有真正的帮助。您是否正在寻找有关如何使当前模型更易于维护的建议,或有关如何重构您的系统以更好地遵循最佳实践的建议?
-
@gahooa 我也尽可能多地在 .NET 中使用(部分是因为那是我的主场),但在某些情况下,例如在继承大型代码库或拥有大量数据时或多或少被存储过程所困扰。
-
我非常强烈地认为您应该将数据库视为具有边界的服务,就像您在 .NET 中对待您的类一样。即它有一个定义良好的接口,并保证它所提供的完整性。版本控制下的存储过程以及对基表的有限访问或无访问权限是其中非常重要的一部分。在数据库层应用尽可能多的约束,以确保数据库能够满足其保证。如果您将数据库用作一组愚蠢的表,那么您将得到的就是这些。
-
@cade Roux,如果可以的话,我会支持你评论一百万次。将数据库用作哑存储是业余数据库设计者的标志。
标签: sql stored-procedures