我有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'
)
)
第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 )
答案 0 :(得分:0)
尝试使用动态SQL:
DECLARE @sql NVARCHAR(max), @where NVARCHAR(max), @WhichOption INT = 1;
SET @sql = 'SELECT A
B
C
FROM X';
IF @WhichOption = 1
SET @where = '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
SET @where = ' 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 ) ';
SET @sql = CONCAT(@sql,' ', @where)
PRINT @sql
EXECUTE sp_executesql @sql
答案 1 :(得分:0)
在过程中保存以下过程。您也可以直接插入物理表中。
declare @varTable Table (columns exactly as Procedures return)
if(condition is met)
begin
insert into @varTable
exec proc1
end
else
begin
insert into @varTable
exec proc2
end
答案 2 :(得分:0)
添加您说的参数,该参数将指示适用什么过滤器:
select XXXXX
from XXXXX
where (@Mode = 1 and ( filter 1 ))
or
(@Mode = 2 and ( filter 2 ))
option(recompile)
如果@Mode参数为1,则它将评估过滤器1,否则它将评估过滤器2。
在语句的末尾添加 option(recompile),因此SQL引擎将用变量的值替换变量,消除将不被评估的过滤器,并生成执行工厂只是要应用的过滤器。
PS:请注意,尽管这些综合查询非常易于编码和维护,并且能够生成完美的功能和最佳执行,但不建议将其用于高要求的应用程序。选项(recompile)强制引擎在每次执行时重新编译并生成一个新的执行计划,如果您的查询需要每分钟执行数百次,那么这会对性能产生显着影响。但是对于偶尔使用,这是完全可以的。