sql - 根据参数值在存储过程中使用不同的 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 )
解决方案
添加您所说的参数,它将指示应用什么过滤器:
select XXXXX
from XXXXX
where (@Mode = 1 and ( filter 1 ))
or
(@Mode = 2 and ( filter 2 ))
option(recompile)
如果@Mode 参数为 1,那么它将评估过滤器 1,否则它将评估过滤器 2。
在语句的末尾添加一个选项(重新编译),以便 SQL 引擎将变量替换为它们的值,消除不会被评估的过滤器,并为您想要应用的过滤器生成一个执行工厂。
PS:请注意,尽管这些包罗万象的查询非常易于编码和维护,并且可以生成完美的功能和最佳执行,但不建议将它们用于高需求的应用程序。选项(重新编译)强制引擎在每次执行时重新编译并生成新的执行计划,如果您的查询需要每分钟执行数百次,这将对性能产生显着影响。但偶尔使用它完全没问题。
推荐阅读
- c# - 如何在 C# 中使用 ASP.NET Core 连接外部身份验证服务器
- flutter - Flutter : 如何让 Flutter 芯片增长和缩小以匹配标签长度
- rust - 如何围绕借来的值实现新类型包装器?
- python - Flask 集成导致帧到字节的 OpenCV 问题
- excel - VBA for excel,包含条件
- php - Laravel 为什么我的下拉菜单在悬停时显示所有元素?
- swift - doesRelativeDateFormatting 不能在 swift 中为将来的日期工作
- python - unittest.TestCase setUpClass 覆盖和继承
- wpf - 来自 Mainwindow.xaml 的用户控件上的交互触发器不起作用
- sql - 如何使用字符串在 SQL 中创建一个范围,以便我可以将其用作排除条件?前任。选择不包括 A1 - A999 的数据