给出这样的存储过程:
create procedure BigParameterizedSearch(@criteria xml, @page int, @pageSize int)
as
...lots of populating table variables & transforming things...
select ..bunch of columns..
from ..bunch of tables..
where ..bunch of (@has_some_filter=0 or ..some filter criteria..) and..
order by ..big case statement depends on criteria..
offset (@page-1)*@pageSize rows
fetch next @pageSize rows only
option (recompile)
及其'摘要'对应物:
create procedure BigParameterizedSearchSummary(@criteria xml, @page int, @pageSize int)
as
...same exact populating table variables & transforming things...
select groupCol, ..various aggregates..
from ..same exact bunch of tables..
where ..same exact bunch of (@has_some_filter=0 or ..some filter criteria..) and..
group by groupCol
order by ..smaller case statement depends on criteria..
offset (@page-1)*@pageSize rows
fetch next @pageSize rows only
option (recompile)
两个存储过程大致相同,只有select
子句和order by
子句不同,“摘要”版本添加了group by
。
现在,问题是,这两个存储过程如何组合?或者,如何避免重复代码?我试图用returns table as return
创建一个公共的表值函数,以便select和group by可以被拉出来调用存储过程而不会影响性能。对returns table as return
的限制使得执行所有复杂的设置变得非常困难,如果我填充表变量,则会为每个页面填充完整的结果集,这会使其减慢太多。除了完整的动态SQL之外还有其他策略吗?
答案 0 :(得分:0)
您可以使用一个视图,其中包含所有表中的所有列以及两个查询所需的所有过滤器,然后针对该视图执行选择和分组。如果我正确理解你的情况,这将为你节省冗余问题。老实说,这类问题正是观点所针对的。
另外,我只是好奇,你真的需要每次都重新编译吗?是否有令人难以置信的事情,你无法负担使用缓存的执行计划?
答案 1 :(得分:0)
你能不能将它分成一个填充表的sproc和一个使用相同参数调用表填充的sproc,然后查询表?
create table Prepop (a int)
go
create procedure uspPopulate (@StartNum int)
as
truncate table Prepop
insert into Prepop values
(@StartNum)
,(@StartNum+1)
,(@StartNum+2)
,(@StartNum+3)
go
create procedure uspCall (@StartNum int, @Summary bit)
as
exec uspPopulate @StartNum = @StartNum
if @Summary = 1
select avg(a) as Avga
from Prepop
else
select a
from Prepop
go
exec uspCall @StartNum = 6, @Summary = 1
exec uspCall @StartNum = 6, @Summary = 0