【发布时间】:2016-05-26 16:32:22
【问题描述】:
我公司的应用程序是围绕大量存储过程设计的,而存储过程痛苦地是非模块化的。例如,一个常见的(反)模式是:
IF @param = MAGIC_VALUE_1
SELECT 20 fields
FROM 4 JOINED TABLES
WHERE SOMEFIELD < 20
ELSE IF @param = MAGIC_VALUE_2
SELECT 20 fields
FROM 4 JOINED TABLES
WHERE SOMEFIELD < 40
ELSE IF @param = MAGIC_VALUE_3
SELECT 20 fields
FROM 4 JOINED TABLES
WHERE SOMEFIELD < 60
...3 or 4 more cases
SELECT 语句本身是合理的业务逻辑,但它们可能非常复杂,并且像这样重复它们很多次对于理解和维护来说是可怕的。
我想将这样的逻辑重构为可重用的例程,就像您可以在 EntityFramework 中执行的操作一样:
query = SELECT 20 fields
FROM 4 JOINED TABLES
IF @param = MAGIC_VALUE_1
query = SELECT * FROM query
WHERE SOMEFIELD < 20
...3 or 4 more cases, differing ONLY in the where clause
甚至更好:
query = SELECT 20 fields
FROM 4 JOINED TABLES
query = SELECT * FROM query
WHERE applyWhereConditionFromMagicParam(query, @param)
有什么方法可以更接近于这种更模块化的查询组合方式,这样我就可以为我们的存储过程带来一些理智?
【问题讨论】:
-
你考虑过视图和表值函数吗?
-
@HABO:我知道它们,是的,但我对它们的用法还不够熟悉,无法完成我需要的工作。你能建议这是如何工作的吗?
-
如果主查询(select ... from ... join...)重复,您可以创建一个视图来处理该部分并根据需要引用它。查找表或 TVF 可能是埋藏一些“神奇价值”管理的方便场所。 (TVF 可用于为
in表达式提供值。)期望为使代码更加模块化而付出性能损失。
标签: sql-server tsql stored-procedures database-design