如何最好地重用相同的存储过程以获取详细信息和摘要

时间:2016-08-29 23:48:16

标签: sql-server tsql sql-server-2014

给出这样的存储过程:

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之外还有其他策略吗?

2 个答案:

答案 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