首页 > 解决方案 > 根据参数值在存储过程中使用不同的 WHERE 子句集

问题描述

我有 2 个存储过程,它们返回我试图合并到单个过程中的相同列。它们都有一组不同的参数,并且都有不同的 WHERE 子句,但它们使用相同的表并选择完全相同的行。

WHERE 子句 1:(使用 @UIOID 和 @Level)

WHERE   (   @UIOID = CASE   WHEN @Level = 'Single' THEN C.C_UIOID_PK        
                WHEN @Level = 'Children' THEN CLC.UIOL_P
                WHEN @Level = 'Parent' THEN CLP.UIOL_C
            END 
        OR  (   @UIOID = '0'    
            AND @Level = 'All'          
            )
            )

Where 第 2 条:(使用@TeamCode、@Year、@IncludeQCodes)

WHERE   C.C_IsChild = 0
AND C.C_MOA <> 'ADD'
AND @TeamCode = C.C_OffOrg
AND C.C_Active = 'Y'
AND (   @Year BETWEEN dbo.f_GetAcYearByDate(C.C_StartDate) AND dbo.f_GetAcYearByDate(C.C_EndDate)
        OR @Year = 0    )
AND (   C.C_InstCode NOT LIKE 'Q%'
        OR  @IncludeQCodes = 1    )   

理想情况下,我想添加一个新参数,它基本上告诉它要运行两个 WHERE 子句中的哪一个,但我似乎无法用 CASE 语句重新创建它,因为据我所知,它们仅适用于单个 WHERE 子句,不是一整套不同的条款

我想这样做,而不必再次重复 select 语句并将整个内容放在 IF 语句中,我也不想将查询放入字符串中。理想情况下,我只想要一个选择语句。

使用临时表的问题是查询本身需要一段时间才能在没有任何参数的情况下运行并且用于实时网站,所以我不希望它必须将所有记录放在临时表中然后过滤它。

使用 CTE 的问题是您不能使用 IF 语句来跟随它,因此这也行不通。

这是我试图实现的逻辑:

SELECT  A
        B
        C    
FROM    X
IF @WhichOption = 1 THEN
    WHERE   (   @UIOID = CASE   WHEN @Level = 'Single' THEN C.C_UIOID_PK        
                WHEN @Level = 'Children' THEN CLC.UIOL_P
                WHEN @Level = 'Parent' THEN CLP.UIOL_C
            END 
        OR  (   @UIOID = '0'    
            AND @Level = 'All'          
            )
        )
ELSE IF @WhichOption = 2 THEN 
    WHERE   C.C_IsChild = 0
    AND C.C_MOA <> 'ADD'
    AND @TeamCode = C.C_OffOrg
    AND C.C_Active = 'Y'
    AND (   @Year BETWEEN dbo.f_GetAcYearByDate(C.C_StartDate) AND     dbo.f_GetAcYearByDate(C.C_EndDate)
                OR @Year = 0    )
    AND (   C.C_InstCode NOT LIKE 'Q%'
            OR  @IncludeQCodes = 1  )  

标签: sqlsql-serverstored-procedures

解决方案


添加您所说的参数,它将指示应用什么过滤器:

select XXXXX
from XXXXX
where (@Mode = 1 and ( filter 1 ))
      or
      (@Mode = 2 and ( filter 2 ))  

option(recompile) 

如果@Mode 参数为 1,那么它将评估过滤器 1,否则它将评估过滤器 2。

在语句的末尾添加一个选项(重新编译),以便 SQL 引擎将变量替换为它们的值,消除不会被评估的过滤器,并为您想要应用的过滤器生成一个执行工厂。

PS:请注意,尽管这些包罗万象的查询非常易于编码和维护,并且可以生成完美的功能和最佳执行,但不建议将它们用于高需求的应用程序。选项(重新编译)强制引擎在每次执行时重新编译并生成新的执行计划,如果您的查询需要每分钟执行数百次,这将对性能产生显着影响。但偶尔使用它完全没问题。


推荐阅读