【问题标题】:Is it possible to make reusable queries or procs in TSQL?是否可以在 SQL 中进行可重用的查询或过程?
【发布时间】: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


【解决方案1】:

在您的示例中,我将使用 case 表达式来减轻痛苦。

Where SomeField < case @param 
                    when MAGIC_VALUE_1 then 20
                    when MAGIC_VALUE_2 then 40
                    when MAGIC_VALUE_3 then 60
                    --etc...
                    end

【讨论】:

  • 这是一个很好的方法。但是,我会在存储过程开始时将上限设为变量,并在查询中使用该变量。
  • @TT 同意。特别是如果需要,它可以很容易地重用该值。
  • 这好多了,谢谢。但是我仍然希望能够在某种可重用的例程中进行这种过滤,因为魔法值过滤逻辑本身就散布在许多过程中,我也想避免这种情况。
  • 您能否提供更多描述性的重复代码示例?对于标量值过滤,没有什么可提供的了。
【解决方案2】:

我可能遗漏了一些东西,但是
只需 function 即可返回 int?

query = SELECT * FROM query
        WHERE SOMEFIELD < db.MagicParam(@param)  

也可以使用 MagicParam 表来做到这一点

【讨论】:

    【解决方案3】:

    您可以创建一个查找表(无论是作为存储过程中的表变量或临时表,还是作为数据库表),其中包含过程名称、MAGIC_VALUE 和对应于MAGIC_VALUE 的值的列。然后,您可以使用过程名称OBJECT_NAME(@@PROCID)@param 在过程中加入此表,以获取与参数和过程关联的值。

    这种方法虽然仍然有点不愉快,但可以让您集中控制魔法,并且在所有受影响的程序中都是一条一致且易于审核的路线。您可以添加一个错误检查,以查看自表更新以来过程名称没有更改,并且只提供了允许的 @param 值。

    【讨论】:

      猜你喜欢
      • 2010-09-08
      • 2014-06-09
      • 2011-07-06
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2018-09-10
      • 2014-06-12
      • 2012-02-14
      相关资源
      最近更新 更多